module NO2OmiRead
  ! --------------------------------------------------------------------
  !
  ! This module reads OMI NO2 and O2-O2 cloud level-2 data,
  ! from HDF file "no2trackyyyymmdd.hdf"
  ! and stores the data in a structure defined below. 
  !
  ! Undefined variables are labelled with the value -999, or -999.
  !
  !   Updated for HDF4 datafiles for coll3 v1.0.1 DOMINO data
  !
  !   Folkert Boersma, KNMI, 23 April 2004
  !
  !---------------------------------------------------------------------

  implicit none

  private
  public :: OmiReadTrack, TOmiNO2Track
  public :: OmiNO2Open, OmiNO2Close

  ! Pressures and kernel defined at 35 layers ( after 1-2-2006 34 layers)
  integer, parameter  :: nr_pressures = 35

  ! Maximum number of OMI pixels per track (i.e. 1644 x 60)
  integer, parameter  :: omimaxpix = 100000

  ! Do not store measurements with solar zenith angles beyond this maximum   
  real,parameter      :: MaxSolarZenithAngle = 80.0

  ! Do not store measurements with viewing angles beyond this maximum   
  real,parameter      :: MaxViewingAngle = 80.0

  ! Record to store NO2 data
  type TOmiNO2Track
     character(8)                  :: trackid
     integer                       :: count
     integer,dimension(omimaxpix)  :: year, month, day
     integer,dimension(omimaxpix)  :: hour, minute, second
     integer,dimension(omimaxpix)  :: fltrop,ltropo,theight,gpxflag
     real,dimension(omimaxpix)     :: latitude,longitude
     real,dimension(4,omimaxpix)   :: cornerlat,cornerlon
     real,dimension(omimaxpix)	   :: no2vcd,no2vcderror
     real,dimension(omimaxpix)	   :: no2vcdtrop,no2vcdtroperror
     real,dimension(omimaxpix)     :: no2vcdstrat,no2vcdstraterror
     real,dimension(omimaxpix)     :: viewingAngle,solarZenithAngle
     real,dimension(nr_pressures,omimaxpix)   :: press, kernel
     real,dimension(omimaxpix)     :: ghostcol,no2scd,no2scdsig,amf,amftrop,amfgeo
     real,dimension(omimaxpix)     :: no2scdstr,cloudfraction,cloudpressure
     real,dimension(omimaxpix)     :: albedo,cloudradfrac
  end type TOmiNO2Track

  ! include HDF parameters
  include 'hdf.f90'

  integer :: file_id = -1     ! identifier for omi HDF file
  integer :: vd_ref_old = -1  ! previous vdata reference

  logical :: firstcall = .true.

contains

  subroutine OmiNO2Open(filnam)
    !--------------------------------------------------------------
    ! Open HDF file for reading and initialize v interface
    ! --------------------------------------------------------------
    !
    implicit none
    !
    integer :: status, i
    integer :: hopen, vfstart
    character(*), intent(in) :: filnam              
    !
    file_id = hopen(filnam, dfacc_read, 0)
    if ( file_id == -1 ) then
       write(*,*) 'OmiNO2Open: failed to open '//trim(filnam)
       stop
    else
    !   write(*,*) 'OmiNO2Open: file '//trim(filnam)
    end if
    status = vfstart(file_id)       

    firstcall = .true.

  end subroutine OmiNO2Open


  subroutine OmiNO2Close
    !------------------------------------------------------------
    ! End v interface and close HDF file omino2.hdf (file_id)
    ! ------------------------------------------------------------
    !
    implicit none
    !
    integer :: status
    integer :: hclose, vfend, hendaccess
    !
    status = vfend(file_id)
    status = hclose(file_id)
    if ( status == -1 ) then
       write(*,*) 'OmiNO2Close: failed to close hdf file '
       stop
    !else
    !   write(*,*) 'OmiNO2Close: hdf file closed'
    end if
    file_id = -1

  end subroutine OmiNO2Close


  !--------------------------------------------------------------  
  !  subroutine OmiReadTrack
  !
  ! Read one track of data from "vdata" records NO2, GEO and ANC
  ! Read also pressure level definitions at beginning of the file
  !
  !--------------------------------------------------------------
  subroutine OmiReadTrack(omiNO2Track)

    type(TOmiNO2Track), intent(out)   :: omiNO2Track

    integer, parameter :: nfields = 2
    integer, parameter :: total_order = 1+1
    integer, parameter :: nfields_NO2 = 17
    integer, parameter :: total_order_NO2 = 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+nr_pressures+1
    integer, parameter :: nfields_GEO = 12
    integer, parameter :: total_order_GEO = 1+1+1+1+1+4+4+1+1+1+1+1
    integer, parameter :: nfields_ANC = 12
    integer, parameter :: total_order_ANC = 1+1+1+1+1+1+1+1+1+1+1+1

    integer, dimension(omimaxpix)  :: vdate,vtime
    integer*2,dimension(omimaxpix) :: vfltrop                            ! 16-bit integer
    integer*2,dimension(omimaxpix) :: vssc,vpixelnr, vimagenr,vgpxflag   ! 16-bit integer
    integer*2,dimension(omimaxpix) :: vtheight,vmheight                  ! 16-bit integer
    integer*1,dimension(omimaxpix) :: vltropo                            ! 8-bit integer
    real, dimension(nr_pressures)  :: alev, blev
    real, dimension(omimaxpix)     :: vlatitude,vlongitude
    real, dimension(omimaxpix)     :: vno2vcd,vno2vcderror
    real, dimension(omimaxpix)     :: vno2vcdtrop,vno2vcdtroperror
    real, dimension(omimaxpix)     :: vno2vcdstrat,vno2vcdstraterror
    real, dimension(omimaxpix)     :: vpsurf,vakerror,vaktroperror
    real, dimension(nr_pressures,omimaxpix)   :: vkernel
    real, dimension(omimaxpix)     :: vghostcol
    real, dimension(omimaxpix)     :: vsza,vvza,vraa,vsaa
    real, dimension(4,omimaxpix)   :: vcornerlon,vcornerlat
    real, dimension(omimaxpix)     :: vscd,vscdsig,vamf,vamftrop
    real, dimension(omimaxpix)     :: vamfgeo,vscdstr,vclfrac
    real, dimension(omimaxpix)     :: vcltpres,valbclr,vcrfrac,vfcvcdtr

    character(len=80)              :: file_name
    integer                        :: ipix, nnegatives
    integer                        :: sfstart, ifail, sds_id
    integer                        :: istat, attributes, num_type
    integer                        :: sffinfo, n_datasets, n_file_attrs
    integer                        :: sfend, sfrnatt, sfrcatt, sffattr
    integer                        :: vd_ref

    real, dimension(total_order*nr_pressures+1)  :: databuf
    real, dimension(total_order_NO2*omimaxpix+1) :: databuf_NO2
    real, dimension(total_order_GEO*omimaxpix+1) :: databuf_GEO
    real, dimension(total_order_ANC*omimaxpix+1) :: databuf_ANC

    integer :: num_of_records, buf_size
    integer :: records_read

    integer :: i, status
    integer :: hopen, vfstart
    logical :: start
    integer :: vsfgid, vsfatch, vsfdtch, vsfgnat
    integer :: vsfgcat, vsfnats, vsfinq, vsfrd

    integer,dimension(4) :: sd_id, rank, sd_index
    integer              :: sfselect, heprnt, vd_id

    character(len=11)  :: fieldname_list_p =   'a_lev,b_lev'
    character(len=110) :: fieldname_list_NO2 = 'date,time,lon,lat,vcd,sigvcd,vcdtrop,sigvcdt,vcdstrat,sigvcds,fltrop,psurf,sigvcdak,sigvcdtak,kernel,ghostcol'    
    !character(len=110) :: fieldname_list_GEO = 'sza,vza,raa,ssc,loncorn,latcorn'
    character(len=110) :: fieldname_list_GEO = 'sza,vza,saa,raa,ssc,loncorn,latcorn,pixelnr,imagenr,gpxflag,theight,mheight'    
    !character(len=110) :: fieldname_list_ANC = 'scd,amf,amftrop,amfgeo,scdstr,clfrac,cltpres,albclr,crfrac,ltropo'
    character(len=110) :: fieldname_list_ANC = 'scd,sigscd,amf,amftrop,amfgeo,scdstr,clfrac,cltpres,albclr,crfrac,ltropo,fcvcdtr'
    
    character(40)            :: pressureUnit, pressureFormula
    character(8)             :: no2trackid
    integer                  :: nrOfPressures, no2tracknr
    integer, dimension(6)    :: start_date, end_date

    character(len=nfields*9) :: fn_list_file
    integer                  :: vcount, vcountp, vcountx
    integer                  :: interlace_mode, vdatasize, vsfisat
    integer                  :: vsfelts, vsfsfld, vsfread, vsfnpak, vsqfname, vsfgnam, vsffnd

    character(len=64)        :: vdata_name, vdata_name2

    ! Remove previous track
    omiNO2Track%count = 0

    ! Check whether omi file has been opened
    if ( file_id == -1 ) then
       write(*,*) 'OmiReadTrack: ERROR hdf file has not yet been opened'
       stop
    end if

    if ( firstcall ) then

       !---------------------------------------------------
       ! reading pressure grid information
       !---------------------------------------------------

       ! find pressure grid vdata
       vd_ref = vsffnd(file_id, 'pressure_grid')

       ! check for availablility
       if ( vd_ref == -1 ) then
          write(*,*) 'OmiReadTrack: ERROR pressure definition not found'
          stop
       end if

       ! Attach to the vdata for reading
       vd_id = vsfatch(file_id, vd_ref, 'r')

       ! Inquire vdata:
       status = vsfinq(vd_id,vcountp,interlace_mode, &
            fn_list_file,vdatasize,vdata_name)
       
       ! Get number of records in this vdata
       vcountp = vsfelts(vd_id)

       if ( vcountp /= nr_pressures ) then
          write(*,*)'OmiReadTrack: ERROR vcountp <> no.levels, STOP'
          write(*,*)'vcountp, no.levels = ',vcountp,nr_pressures
          stop
       end if

       ! initializing the fields for read access status 
       status = vsfsfld(vd_id, fieldname_list_p)
       
       ! read the data
       records_read = vsfread(vd_id, databuf, vcountp, full_interlace)

       ! Unpack databuf into separate variables
       buf_size = 4*total_order*vcountp
       
       status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_p, databuf, buf_size, records_read, 'a_lev', alev)
       if ( status /= 0 ) then
          print*,'OmiReadTrack: Error in reading a_lev data'
          stop
       end if
       status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_p, databuf, buf_size, records_read, 'b_lev', blev)
       if (status /= 0) then
          print*,'OmiReadTrack: Error in reading b_lev data'
          stop
       end if

       ! Get three attributes: 
       !   1. Pressure unit  2. Pressure level formula 3. Nr of levels
       status = vsfgnat(vd_id, hdf_vdata, 0, pressureUnit)
       status = vsfgnat(vd_id, hdf_vdata, 1, pressureFormula)
       status = vsfgnat(vd_id, hdf_vdata, 2, nrOfPressures)

       ! Detach from the vdata
       status = vsfdtch(vd_id)  

       ! Set vd_ref for next track: skip three pressure attributes
       vd_ref = vsfgid(file_id, vd_ref)
       vd_ref = vsfgid(file_id, vd_ref)
       vd_ref = vsfgid(file_id, vd_ref)
       vd_ref_old = vd_ref

       firstcall = .false.

    end if

    !---------------------------------------------------
    ! reading NO2 table
    !---------------------------------------------------

    ! Find the next vdata in the file
    vd_ref = vsfgid(file_id, vd_ref_old)
       
    ! Check vd_ref: end of file ?
    if ( vd_ref == -1 ) then
       return
    end if
    
    ! Attach to the vdata for reading
    vd_id = vsfatch(file_id, vd_ref, 'r')
    
    ! Get and check name of this vdata set
    status = vsfgnam(vd_id, vdata_name)
    
    do while ( vdata_name(1:3) /= 'NO2' ) 
    status = vsfdtch(vd_id)  
      vd_ref = vsfgid(file_id, vd_ref)
      if ( vd_ref == -1 ) then
         return
      end if
      vd_id = vsfatch(file_id, vd_ref, 'r')      
      status = vsfgnam(vd_id, vdata_name)
    enddo
    if ( vdata_name(1:3) /= 'NO2' ) then
       write(*,*) 'OmiReadTrack: ERROR NO2 table not found'
       write(*,*) vdata_name
       stop
    end if
       
    ! Get number of records in this vdata
    vcount = vsfelts(vd_id)
    if ( vcount > omimaxpix ) then
       write(*,*)'OmiReadTrack: ERROR vcount > omimaxpix, STOP'
       write(*,*)'vcount, omimaxpix = ',vcount,omimaxpix
       stop
    end if

    ! initializing the fields for read access
    status = vsfsfld(vd_id, fieldname_list_NO2)

    ! read the data
    records_read = vsfread(vd_id, databuf_NO2, vcount, full_interlace)

    ! Unpack databuf into separate variables
    buf_size = 4*total_order_NO2*vcount

    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_NO2, databuf_NO2, buf_size, records_read, 'date', vdate)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_NO2, databuf_NO2, buf_size, records_read, 'time', vtime)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_NO2, databuf_NO2, buf_size, records_read, 'lon', vlongitude)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_NO2, databuf_NO2, buf_size, records_read, 'lat', vlatitude)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_NO2, databuf_NO2, buf_size, records_read, 'vcd', vno2vcd)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_NO2, databuf_NO2, buf_size, records_read, 'sigvcd', vno2vcderror)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_NO2, databuf_NO2, buf_size, records_read, 'vcdtrop', vno2vcdtrop)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_NO2, databuf_NO2, buf_size, records_read, 'sigvcdt', vno2vcdtroperror)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_NO2, databuf_NO2, buf_size, records_read, 'vcdstrat', vno2vcdstrat)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_NO2, databuf_NO2, buf_size, records_read, 'sigvcds', vno2vcdstraterror)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_NO2, databuf_NO2, buf_size, records_read, 'fltrop', vfltrop)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_NO2, databuf_NO2, buf_size, records_read, 'psurf', vpsurf)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_NO2, databuf_NO2, buf_size, records_read, 'sigvcdak', vakerror)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_NO2, databuf_NO2, buf_size, records_read, 'sigvcdtak', vaktroperror)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_NO2, databuf_NO2, buf_size, records_read, 'kernel', vkernel)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_NO2, databuf_NO2, buf_size, records_read, 'ghostcol', vghostcol)

    ! Get four attributes: 
    ! 1. orbit identifier  2. orbit number 3. start time 4. end time
    status = vsfgnat(vd_id, hdf_vdata, 0, no2trackid)
    status = vsfgnat(vd_id, hdf_vdata, 1, no2tracknr)
    status = vsfgnat(vd_id, hdf_vdata, 2, start_date)
    status = vsfgnat(vd_id, hdf_vdata, 3, end_date)

    ! Detach from the vdata
    status = vsfdtch(vd_id)  

    ! Set vd_ref for next track: skip four vdata's (the attributes)
    vd_ref = vsfgid(file_id, vd_ref)
    vd_ref = vsfgid(file_id, vd_ref)
    vd_ref = vsfgid(file_id, vd_ref)
    vd_ref = vsfgid(file_id, vd_ref)
    vd_ref_old = vd_ref

    !---------------------------------------------------
    ! reading GEO table
    !---------------------------------------------------

    ! Find the next vdata in the file
    vd_ref = vsfgid(file_id, vd_ref_old)

    ! Attach to the vdata for reading
    vd_id = vsfatch(file_id, vd_ref, 'r')

    ! Get and check name of this vdata set
    status = vsfgnam(vd_id, vdata_name2)
    if ( vdata_name2(1:3) /= 'GEO' ) then
       write(*,*) 'OmiReadTrack: ERROR GEO table not found'
       write(*,*) vdata_name2
       stop
    end if
       
    ! Get number of records in this vdata, check consistency
    vcountx = vsfelts(vd_id)
    if ( vcountx /= vcount ) then
       write(*,*)'OmiReadTrack: ERROR GEO vcountx <> vcount, STOP'
       write(*,*)'vcount, vcountx = ',vcount,vcountx
       stop
    end if

    ! initializing the fields for read access
    status = vsfsfld(vd_id, fieldname_list_GEO)

    ! read the data
    records_read = vsfread(vd_id, databuf_GEO, vcount, full_interlace)

    ! Unpack databuf into separate variables
    buf_size = 4*total_order_GEO*vcount

    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_GEO, databuf_GEO, buf_size, records_read, 'sza', vsza)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_GEO, databuf_GEO, buf_size, records_read, 'vza', vvza)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_GEO, databuf_GEO, buf_size, records_read, 'saa', vsaa)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_GEO, databuf_GEO, buf_size, records_read, 'raa', vraa)   
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_GEO, databuf_GEO, buf_size, records_read, 'ssc', vssc)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_GEO, databuf_GEO, buf_size, records_read, 'loncorn', vcornerlon)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_GEO, databuf_GEO, buf_size, records_read, 'latcorn', vcornerlat)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_GEO, databuf_GEO, buf_size, records_read, 'pixelnr', vpixelnr)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_GEO, databuf_GEO, buf_size, records_read, 'imagenr', vimagenr)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_GEO, databuf_GEO, buf_size, records_read, 'gpxflag', vgpxflag)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_GEO, databuf_GEO, buf_size, records_read, 'theight', vtheight)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_GEO, databuf_GEO, buf_size, records_read, 'mheight', vmheight)

    ! Detach from the vdata
    status = vsfdtch(vd_id)  

    ! Set vd_ref for next track: skip four vdata's (the attributes)
    !vd_ref = vsfgid(file_id, vd_ref)
    !vd_ref = vsfgid(file_id, vd_ref)
    !vd_ref = vsfgid(file_id, vd_ref)
    !vd_ref = vsfgid(file_id, vd_ref)
    vd_ref_old = vd_ref
   
    !---------------------------------------------------
    ! reading ANC table
    !---------------------------------------------------

    ! Find the next vdata in the file
    vd_ref = vsfgid(file_id, vd_ref_old)

    ! Attach to the vdata for reading
    vd_id = vsfatch(file_id, vd_ref, 'r')

    ! Get name of this vdata set
    status = vsfgnam(vd_id, vdata_name2)
    if ( vdata_name2(1:3) /= 'ANC' ) then
       write(*,*) 'OmiReadTrack: ERROR ANC table not found'
       stop
    end if
       
    ! Get number of records in this vdata, check consistency
    vcountx = vsfelts(vd_id)
    if ( vcountx /= vcount ) then
       write(*,*)'OmiReadTrack: ERROR ANC vcountx <> vcount, STOP'
       write(*,*)'vcount, vcountx = ',vcount,vcountx
       stop
    end if

    ! initializing the fields for read access
    status = vsfsfld(vd_id, fieldname_list_ANC)

    ! read the data
    records_read = vsfread(vd_id, databuf_ANC, vcount, full_interlace)

    ! Unpack databuf into separate variables
    buf_size = 4*total_order_ANC*vcount

    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_ANC, databuf_ANC, buf_size, records_read, 'scd', vscd)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_ANC, databuf_ANC, buf_size, records_read, 'scdsig', vscdsig)    
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_ANC, databuf_ANC, buf_size, records_read, 'amf', vamf)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_ANC, databuf_ANC, buf_size, records_read, 'amftrop', vamftrop)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_ANC, databuf_ANC, buf_size, records_read, 'amfgeo', vamfgeo)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_ANC, databuf_ANC, buf_size, records_read, 'scdstr', vscdstr)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_ANC, databuf_ANC, buf_size, records_read, 'clfrac', vclfrac)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_ANC, databuf_ANC, buf_size, records_read, 'cltpres', vcltpres)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_ANC, databuf_ANC, buf_size, records_read, 'albclr', valbclr)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_ANC, databuf_ANC, buf_size, records_read, 'crfrac', vcrfrac)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_ANC, databuf_ANC, buf_size, records_read, 'ltropo', vltropo)
    status = vsfnpak(vd_id, hdf_vsunpack, fieldname_list_ANC, databuf_ANC, buf_size, records_read, 'fcvcdtr', vfcvcdtr)
    
    ! Detach from the vdata
    status = vsfdtch(vd_id)  

    ! Set vd_ref for next track (vd_ref_old is module global variable)
    vd_ref_old = vd_ref

    !---------------------------------------------------
    ! store all data in the structure
    !---------------------------------------------------

    ! store track id
    omiNO2Track%trackid = no2trackid

    ipix = 0

    do i = 1, vcount
       
       ! check solar zenith angle
       if(  (vsza(i) < 0.0) .or. (vsza(i) > 90.0) ) then
          cycle	! skip pixel
       endif

       ! filter high solar zenith angles
       if( vsza(i) > MaxSolarZenithAngle ) then
          cycle	 ! skip pixel
       endif

       ! check viewing zenith angle
       if( ( vvza(i) < 0.0 ) .or. &
           ( vvza(i) > MaxViewingAngle ) ) then
          cycle	! skip pixel
       endif

       ! check instrument mode (zoom-mode show anomalous behaviour)
       if( ( vssc(i) >= 8 )  ) then
          exit	! skip track assuming that a track is made in the same instrument mode
       endif

       ! Accept pixel, copy content to structure
       ipix = ipix+1
       if ( ipix > omimaxpix ) then
          write(*,*) 'OMIReadTrack ERROR: max number of pixels exceeded',&
               ' (', omimaxpix, ')'
          stop
       endif

       ! pixel time
       omiNO2Track%year(ipix)   = INT(vdate(i)/10000)
       omiNO2Track%month(ipix)  = MOD(INT(vdate(i)/100),100)
       omiNO2Track%day(ipix)    = MOD(INT(vdate(i)),100)

       omiNO2Track%hour(ipix)   = MOD(INT(vtime(i)/10000),100)
       omiNO2Track%minute(ipix) = MOD(INT(vtime(i)/100),100)
       omiNO2Track%second(ipix) = MOD(vtime(i),100)                     

       if ( vlongitude(i) > 180. ) then
          vlongitude(i) = vlongitude(i)-360.  		     
       endif
       omiNO2Track%longitude(ipix)   = vlongitude(i)
       omiNO2Track%latitude(ipix)    = vlatitude(i)
       ! corner coordinates
       if ( vcornerlon(1,i) > 180. ) then
          vcornerlon(1,i)=vcornerlon(1,i)-360.  		     
       end if
       if ( vcornerlon(2,i) > 180. ) then
          vcornerlon(2,i)=vcornerlon(2,i)-360.  		     
       end if
       if ( vcornerlon(3,i) > 180. ) then
          vcornerlon(3,i)=vcornerlon(3,i)-360.  		     
       end if
       if (vcornerlon(4,i) > 180.)then
          vcornerlon(4,i)=vcornerlon(4,i)-360.  		     
       end if
       omiNO2Track%cornerlon(:,ipix)	  = vcornerlon(:,i)
       omiNO2Track%cornerlat(:,ipix)	  = vcornerlat(:,i)
       omiNO2Track%no2vcd(ipix)  	      = vno2vcd(i)
       omiNO2Track%no2vcderror(ipix)	  = vno2vcderror(i)
       omiNO2Track%no2vcdtrop(ipix)	      = vno2vcdtrop(i)
       omiNO2Track%no2vcdtroperror(ipix)  = vno2vcdtroperror(i)
       omiNO2Track%no2vcdstrat(ipix)	  = vno2vcdstrat(i)
       omiNO2Track%no2vcdstraterror(ipix) = vno2vcdstraterror(i)
       omiNO2Track%fltrop(ipix)  	      = vfltrop(i)
       omiNO2Track%press(:,ipix) 	      = alev(:) + vpsurf(i)*blev(:)
       omiNO2Track%kernel(:,ipix)	      = vkernel(:,i)
       omiNO2Track%ghostcol(ipix)	      = vghostcol(i)
       omiNO2Track%solarZenithAngle(ipix) = vsza(i)
       omiNO2Track%viewingAngle(ipix)	  = vvza(i)
       omiNO2Track%theight(ipix)          = vtheight(i)
       omiNO2Track%no2scd(ipix)  	      = vscd(i)
       omiNO2Track%no2scdsig(ipix)        = vscdsig(i)
       omiNO2Track%amf(ipix)		      = vamf(i)
       omiNO2Track%amftrop(ipix) 	      = vamftrop(i)
       omiNO2Track%amfgeo(ipix)  	      = vamfgeo(i)
       omiNO2Track%no2scdstr(ipix)	      = vscdstr(i)
       omiNO2Track%cloudfraction(ipix)	  = vclfrac(i)
       omiNO2TRack%cloudpressure(ipix)    = vcltpres(i)       
       omiNO2Track%albedo(ipix)  	      = valbclr(i)
       omiNO2Track%cloudradfrac(ipix)	  = vcrfrac(i)
       omiNO2Track%ltropo(ipix)  	      = vltropo(i)
       omiNO2TRack%gpxflag(ipix)          = vgpxflag(i)              
       ! Repair 16-bit unsigned integer trouble
       if (omiNO2Track%gpxflag(ipix) < 0) then
          omiNO2Track%gpxflag(ipix)=omiNO2Track%gpxflag(ipix)+65536
       endif       
                       
    end do

    omiNO2Track%count = ipix

    write(*,'(a,i5,a,i5,a)') &
         ' OmiReadTrack: '//trim(vdata_name)//', storing ',&
         ipix,'  (of ',vcount,') pixels'


end subroutine OmiReadTrack


end module NO2OmiRead

