Browse Source

Pytho all Sensor OK

Default Seadas User 8 years ago
parent
commit
18a05d698a
2 changed files with 126 additions and 44 deletions
  1. 116 38
      class_KdJamet.py
  2. 10 6
      test_class_KdNN.py

+ 116 - 38
class_KdJamet.py

@@ -1,6 +1,8 @@
-#!/usr/bin/python
 # -*- coding: utf-8 -*-
-
+# class for Jamet Neural Network Kd inversion.
+# Python version :
+# 2016-05-11 D.Dessailly david.dessailly@univ-littoral.fr
+# LOG (Laboratoire d'Oceanoligie et Geoscience)
 import numpy as np
 import sys
 import os
@@ -8,20 +10,24 @@ import os
 Sensor = {'idSEAWIFS' : 0, 'idMODIS' : 1, 'idMERIS' : 2}
 NBWL = 6
 
+#
+# Class to handle Jamet's Kd processing for MERIS/OLCI, SEAWIFS and MODIS Sensor
+#
 class KdJamet:
-  #
+  # -- default __init__ Method +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   # Input :
-  # idSensor : valid values -> [idSEAWIFS, idMODIS, idMERIS]
-  #
+  # idSensor : valid values -> ['idSEAWIFS', 'idMODIS', 'idMERIS']
+  # --
   def __init__(self, idSensor):
     self.sensor = idSensor
     try:
       self.lutpath = os.getenv('KD_LUTS_PATH')
     except:
-      print "KD_LUT_PATH not set, add it to your environment variables"
+      print "KD_LUTS_PATH not set, add it to your environment variables\n for bash user add the following line to your .bashrc file :\n export KD_LUTS_PATH=/where/are/my/KD/LUTS\n then:\n source ~/.bashrc"
       sys.exit()
     
-    if Sensor.has_key(idSensor):
+    if idSensor in Sensor:
+      # 
       self.init_variables()
       try:
         self.read_LUTs_Kd()
@@ -30,16 +36,16 @@ class KdJamet:
         raise
         sys.exit()
     else:
-      print "invalid Sensor ID : %s" % (idSensor)
+      print "invalid Sensor ID : %s\n valid values : idSEAWIFS, idMODIS, idMERIS" % (idSensor)
+      sys.exit()
   
-  # - METHODE init_variables ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  # Perceptron parameters setting and array initialization for each Sensor
+  # -- METHOD init_variables ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  # Sensor dependants variables and Perceptron parameters setting 
   # --
   def init_variables(self):
     print "class KdJamet.init_variables Method"
     # =======================================================================================================
     # MERIS / OLCI 
-    # =======================================================================================================
     if self.sensor == 'idMERIS':
       self.WL = np.array([413, 443, 490, 510, 560, 665])
       # Variables definiton for network Rrs490/Rrs555 >= .85 -------------------------------------------------
@@ -60,7 +66,7 @@ class KdJamet:
       self.rsup_LUT_MOY = "Moy_KdOLCI_IOCCG_NOMAD_BOUM_ss_12_COASTCOLOUR_412_to_670_log_Kd_lambda_merge_seuil_15_angle_publi_ss_620.dat"
       self.rsup_LUT_ECART = "Ecart_KdOLCI_IOCCG_NOMAD_BOUM_ss_12_COASTCOLOUR_412_to_670_log_Kd_lambda_merge_seuil_15_angle_publi_ss_620.dat"
 
-      # Variables definiton for network Variables definiton for network < .85 -----------------------------------
+      # Variables definiton for network < .85 -----------------------------------
       # nombre de couches cachees - hidden layer number
       self.rinf_NC=2
       # input data number*/
@@ -77,8 +83,88 @@ class KdJamet:
       self.rinf_LUT_POIDS = "KdOLCI_poids_IOCCG_NOMAD_BOUM_ss_12_COASTCOLOUR_443_to_670_log_Kd_lambda_merge_seuil_15_angle_ascii_6x1_hh_5_5_switch_110416.sn"
       self.rinf_LUT_MOY = "Moy_KdOLCI_IOCCG_NOMAD_BOUM_ss_12_COASTCOLOUR_412_to_670_log_Kd_lambda_merge_seuil_15_angle_publi_ss_620.dat"
       self.rinf_LUT_ECART = "Ecart_KdOLCI_IOCCG_NOMAD_BOUM_ss_12_COASTCOLOUR_412_to_670_log_Kd_lambda_merge_seuil_15_angle_publi_ss_620.dat"
+      
+    # =======================================================================================================
+    # MODIS
+    if self.sensor == 'idMODIS':
+      self.WL = np.array([412, 443, 488, 531, 547, 667])
+      # Variables definiton for network Rrs490/Rrs555 >= .85 -------------------------------------------------
+      # hidden layer number 
+      self.rsup_NC=2
+      # input data number
+      self.rsup_NE=5
+      # number of neuron in the first hidden layer 
+      self.rsup_NC1=5
+      # number of neuron in the second hidden layer
+      self.rsup_NC2=4
+      # nb output
+      self.rsup_NS=1
+      # nb input + nb output*/
+      self.rsup_NES=6
+      # LUTs file names 
+      self.rsup_LUT_POIDS = "KdMODIS_poids_IOCCG_NOMAD_BOUM_ss_12_COASTCOLOUR_443_to_555_log_Kd_lambda_merge_seuil_15_angle_ascii_6x1_hh_5_4_publi_CSIRO.sn"
+      self.rsup_LUT_MOY = "Moy_KdMODIS_IOCCG_NOMAD_BOUM_ss_12_COASTCOLOUR_412_to_555_log_Kd_lambda_merge_seuil_15_ss_645_publi_sup_CSIRO.dat"
+      self.rsup_LUT_ECART = "Ecart_KdMODIS_IOCCG_NOMAD_BOUM_ss_12_COASTCOLOUR_412_to_555_log_Kd_lambda_merge_seuil_15_ss_645_publi_sup_CSIRO.dat"
 
-    #LUTs arrays definition
+      # Variables definiton for network < .85 -----------------------------------
+      # nombre de couches cachees - hidden layer number
+      self.rinf_NC=2
+      # input data number*/
+      self.rinf_NE=6
+      # number of neuron in the first hidden layer
+      self.rinf_NC1=10
+      # number of neuron in the second hidden layer
+      self.rinf_NC2=7
+      # nb output
+      self.rinf_NS=1
+      # nb input + nb output
+      self.rinf_NES=7
+      #LUTs file names
+      self.rinf_LUT_POIDS = "KdMODIS_poids_IOCCG_NOMAD_BOUM_ss_12_COASTCOLOUR_443_to_670_log_Kd_lambda_merge_seuil_15_angle_ascii_6x1_hh_10_7_publi_CSIRO.sn"
+      self.rinf_LUT_MOY = "Moy_KdMODIS_IOCCG_NOMAD_BOUM_ss_12_COASTCOLOUR_412_to_670_log_Kd_lambda_merge_seuil_15_ss_645_publi_inf_CSIRO.dat"
+      self.rinf_LUT_ECART = "Ecart_KdMODIS_IOCCG_NOMAD_BOUM_ss_12_COASTCOLOUR_412_to_670_log_Kd_lambda_merge_seuil_15_ss_645_publi_inf_CSIRO.dat"
+      
+    # =======================================================================================================
+    # SEAWIFS
+    if self.sensor == 'idSEAWIFS':
+      self.WL = np.array([412, 443, 490, 510, 555, 670])
+    # Variables definiton for network Rrs490/Rrs555 >= .85 -------------------------------------------------
+      # hidden layer number 
+      self.rsup_NC=2
+      # input data number
+      self.rsup_NE=5
+      # number of neuron in the first hidden layer 
+      self.rsup_NC1=4
+      # number of neuron in the second hidden layer
+      self.rsup_NC2=4
+      # nb output
+      self.rsup_NS=1
+      # nb input + nb output*/
+      self.rsup_NES=6
+      # LUTs file names 
+      self.rsup_LUT_POIDS = "KdSeaWiFS_poids_IOCCG_NOMAD_BOUM_ss_12_COASTCOLOUR_443_to_555_log_Kd_lambda_merge_seuil_15_angle_ascii_6x1_hh_4_4_publi_200715.sn"
+      self.rsup_LUT_MOY = "Moy_KdSeaWiFS_IOCCG_NOMAD_BOUM_ss_12_COASTCOLOUR_412_to_670_log_Kd_lambda_merge_seuil_15_angle_publi_160715.dat"
+      self.rsup_LUT_ECART = "Ecart_KdSeaWiFS_IOCCG_NOMAD_BOUM_ss_12_COASTCOLOUR_412_to_670_log_Kd_lambda_merge_seuil_15_angle_publi_160715.dat"
+
+      # Variables definiton for network < .85 -----------------------------------
+      # nombre de couches cachees - hidden layer number
+      self.rinf_NC=2
+      # input data number*/
+      self.rinf_NE=6
+      # number of neuron in the first hidden layer
+      self.rinf_NC1=5
+      # number of neuron in the second hidden layer
+      self.rinf_NC2=5
+      # nb output
+      self.rinf_NS=1
+      # nb input + nb output
+      self.rinf_NES=7
+      #LUTs file names
+      self.rinf_LUT_POIDS = "KdSeaWiFS_poids_IOCCG_NOMAD_BOUM_ss_12_COASTCOLOUR_443_to_670_log_Kd_lambda_merge_seuil_15_angle_ascii_6x1_hh_5_5_publi_160715_ter.sn"
+      self.rinf_LUT_MOY = "Moy_KdSeaWiFS_IOCCG_NOMAD_BOUM_ss_12_COASTCOLOUR_412_to_670_log_Kd_lambda_merge_seuil_15_angle_publi_160715.dat"
+      self.rinf_LUT_ECART = "Ecart_KdSeaWiFS_IOCCG_NOMAD_BOUM_ss_12_COASTCOLOUR_412_to_670_log_Kd_lambda_merge_seuil_15_angle_publi_160715.dat"
+      
+    # LUTs arrays definition
     self.rsup_b1 = np.zeros((self.rsup_NC1), dtype=np.float64) 
     self.rsup_b2 = np.zeros((self.rsup_NC2), dtype=np.float64) 
     self.rsup_b3 = 0.
@@ -96,27 +182,16 @@ class KdJamet:
     self.rinf_w3 = np.zeros((self.rinf_NC2), dtype=np.float64)
     self.rinf_moy = np.zeros((self.rinf_NES), dtype=np.float64)
     self.rinf_ecart = np.zeros((self.rinf_NES), dtype=np.float64)
-    
-    # =======================================================================================================
-    # MODIS
-    # =======================================================================================================
-    if self.sensor == 'idMODIS':
-      self.WL = np.array([412, 443, 488, 531, 547, 667])
-    # =======================================================================================================
-    # SEAWIFS
-    # =======================================================================================================
-    if self.sensor == 'idSEAWIFS':
-      self.WL = np.array([412, 443, 490, 510, 555, 670])
   
-  # -- METHODE read_LUTs_Kd ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  # perceptron weights LUTs reading
-  # LUTS are expected to be located in environment variable : $KD_LUTS_PATH
+  # -- METHOD read_LUTs_Kd ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  # Perceptron LUTs reading
+  # LUTS are expected to be located in the directory defined by environment variable $KD_LUTS_PATH (cf: __init__)
   # --
   def read_LUTs_Kd(self):
     print "class KdJamet.read_LUTs_Kd Method"
     # ----------------------------------------------------------------------------------
     #  < .85 weights settings
-    print "  class KdJamet.read_LUTs_Kd : read weights file for Rrs%d/Rrs%d < .85: %s/%s" % (self.WL[2], self.WL[4],self.lutpath, self.rinf_LUT_POIDS)
+    #print "  KdJamet.read_LUTs_Kd : read weights file for Rrs%d/Rrs%d < .85: %s/%s" % (self.WL[2], self.WL[4],self.lutpath, self.rinf_LUT_POIDS)
     weights = np.loadtxt( "%s/%s" % (self.lutpath, self.rinf_LUT_POIDS), skiprows=1)
     base = 0
     self.rinf_b1 = weights[base:base+self.rinf_NC1,2]
@@ -136,16 +211,16 @@ class KdJamet:
     usedData = np.array([1,2,3,4,5,6,8])
     if self.sensor == 'idMODIS':
       usedData = np.array([1,2,3,4,6,7,9])
-    print "  class KdJamet.read_LUTs_Kd : read mean file : %s/%s" % (self.lutpath, self.rinf_LUT_MOY)
+    #print "  KdJamet.read_LUTs_Kd : read mean file : %s/%s" % (self.lutpath, self.rinf_LUT_MOY)
     moy = np.loadtxt( "%s/%s" % (self.lutpath, self.rinf_LUT_MOY))
     self.rinf_moy = moy[usedData]
-    print "  class KdJamet.read_LUTs_Kd : read ecart file : %s/%s" % (self.lutpath, self.rinf_LUT_ECART)
+    #print "  class KdJamet.read_LUTs_Kd : read ecart file : %s/%s" % (self.lutpath, self.rinf_LUT_ECART)
     ecart = np.loadtxt( "%s/%s" % (self.lutpath, self.rinf_LUT_ECART))
     self.rinf_ecart = ecart[usedData]
     
     # ----------------------------------------------------------------------------------
     #  >= .85 weights settings
-    print "  class KdJamet.read_LUTs_Kd : read weights file for Rrs%d/Rrs%d >= .85: %s/%s" % (self.WL[2], self.WL[4], self.lutpath, self.rsup_LUT_POIDS)
+    #print "  KdJamet.read_LUTs_Kd : read weights file for Rrs%d/Rrs%d >= .85: %s/%s" % (self.WL[2], self.WL[4], self.lutpath, self.rsup_LUT_POIDS)
     weights = np.loadtxt( "%s/%s" % (self.lutpath, self.rsup_LUT_POIDS), skiprows=1)
     base = 0
     self.rsup_b1 = weights[base:base+self.rsup_NC1,2]
@@ -170,10 +245,10 @@ class KdJamet:
     ecart = np.loadtxt( "%s/%s" % (self.lutpath, self.rsup_LUT_ECART))
     self.rsup_ecart = ecart[usedData]
     
-  # -- METHODE compute_allKd ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  # Kd computing at all Sensor used WaveLength
+  # -- METHOD compute_allKd ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  # Kd computing at all Sensor WaveLength (vary for each sensor)
   # Inputs -
-  # - indata : array[] [ Rrs443, Rrs490, Rrs510, Rrs55, Rrs665 ]
+  # - indata : array[] [ Rrs443, Rrs490, Rrs510, Rrs555, Rrs665 ]
   # Output -
   # - return Kd[] at Sensor Wave Length
   # --
@@ -190,6 +265,7 @@ class KdJamet:
       idLambda = self.rsup_NE-1
       FLAGinf = False
     inc = 0
+    # compute Kd for each Wave Length of sensor used as iput
     for wl in self.WL:
       indata[idLambda] = wl
       if FLAGinf == True:
@@ -199,12 +275,13 @@ class KdJamet:
       inc = inc+1
     return outKd
     
-  # --  METHODE passe_avant_sup ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  # --  METHOD passe_avant_sup ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   # Kd computing  for Rrs490/Rrs55 >= .85 at ONE WaveLength
   # Inputs -
   # - indata : array[rinf_NE] [ Rrs443, Rrs490, Rrs510, Rrs55, Lambda ]
   # Output -
-  # - return y (Kd) at indata Wave Length
+  # - return y (Kd) at indata Wave Length {the wave length can be any value between min and max Wave length
+  #   used for the sensor  }
   # --
   def passe_avant_sup(self, indata):
     # Normalization
@@ -228,12 +305,13 @@ class KdJamet:
     y = 10.**y
     return(y)
   
-  # --   METHODE passe_avant_inf ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  # --   METHOD passe_avant_inf ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   # Kd computing  for Rrs490/Rrs55 < .85 at ONE WaveLength
   # Inputs 
   # - indata : array[rinf_NE] [ Rrs443, Rrs490, Rrs510, Rrs55, Rrs665, Lambda ]
   # Output -
-  # - return y (Kd) at indata Wave Length
+  # - return y (Kd) at indata Wave Length {the wave length can be any value between min and max Wave length
+  #   used for the sensor  }
   # --
   def passe_avant_inf(self, indata):
     # Normalization

+ 10 - 6
test_class_KdNN.py

@@ -2,18 +2,22 @@
 import class_KdJamet as kdj
 import numpy as np
 import sys
-if len(sys.argv) != 3:
-  print "test_class_KdNN.py   must be launch with two arguments:"
-  print " $ test_class_KdNN.py LOG_KdNeuralNetwork_TestCase_Input.csv your_output.csv"
+if len(sys.argv) != 4:
+  print "test_class_KdNN.py must be launch with three arguments:"
+  print " $ test_class_KdNN.py LOG_KdNeuralNetwork_TestCase_Input.csv your_output.csv idSensor[idMERIS, idSEAWIFS, idMODIS]"
   sys.exit(-1)
-  
-K = kdj.KdJamet('idMERIS')
+
+# class KdJamet instance initialization for seleted sensor (argv[3])
+K = kdj.KdJamet(sys.argv[3])
+# test case Rrs file (argv[1]) reading  (ie: LOG_KdNeuralNetwork_TestCase_Input.csv)
 tab = np.loadtxt(sys.argv[1], skiprows=1)
 
+# array to store Kd results
 KDs = np.zeros(tab.shape,dtype=np.float32)
+# for each line of input file compute the Kd for selected Sensor
 for i in range(tab.shape[0]):
   KDs[i,:] = K.compute_allKd(tab[i,:])
-  
+# write result in argv[2] file
 np.savetxt(sys.argv[2],KDs,fmt='%.7f',header="Kd%d Kd%d Kd%d Kd%d Kd%d Kd%d" %(K.WL[0],K.WL[1],K.WL[2],K.WL[3],K.WL[4],K.WL[5]))