From 55d3cf261e476015f98190decd21c17593ac7ef0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ga=C3=ABlle=20USSEGLIO?= <gaelle.usseglio@cnes.fr>
Date: Tue, 7 Jan 2020 16:39:00 +0000
Subject: [PATCH] ENH : Create a logger for processing chains

---
 python_src/diapOTB.py      | 164 ++++++++++++++++++++++------
 python_src/diapOTB_S1IW.py | 214 +++++++++++++++++++++++++++++--------
 2 files changed, 301 insertions(+), 77 deletions(-)

diff --git a/python_src/diapOTB.py b/python_src/diapOTB.py
index 9255952..a39c35d 100644
--- a/python_src/diapOTB.py
+++ b/python_src/diapOTB.py
@@ -29,23 +29,40 @@ __date__ = "27/10/2017"
 __last_modified__ = "27/10/2017"
 
 # Imports
+import sys
 import logging
 import json
 from jsonschema import validate
 import os
-import sys
 import argparse
 import h5py
 
 import otbApplication as otb
 
-logger = logging.getLogger(__name__)
+
+# Streamer to our log file
+class StreamToLogger(object):
+    """
+    Fake file-like stream object that redirects writes to a logger instance.
+    """
+    def __init__(self, logger, log_level=logging.INFO):
+        self.logger = logger
+        self.log_level = log_level
+
+    def write(self, buf):
+        for line in buf.rstrip().splitlines():
+            self.logger.log(self.log_level, line.rstrip())
+
+    def flush(self):
+        for handler in self.logger.handlers:
+            handler.flush()
+
 
 def validate_json(json, schema):
     try:
         validate(json, schema)
     except Exception as valid_err:
-        print("Invalid JSON: {}".format(valid_err))
+        print("Invalid JSON: {err}".format(err=valid_err))
         return False
     else:
         # Realise votre travail
@@ -66,13 +83,27 @@ if __name__ == "__main__":
     args = parser.parse_args()
     print(args.configfile)
 
+    # Logger initialization
+    logger = logging.getLogger(__name__)
+    logger.setLevel(logging.INFO)
+    
+    LogFormatter = logging.Formatter('%(filename)s :: %(levelname)s :: %(message)s')
+
+    # Create console handler with a high log level (warning level)
+    stream_handler = logging.StreamHandler()
+    stream_handler.setLevel(logging.WARNING)
+
+    # Add Handlers
+    logger.addHandler(stream_handler)
+    
+
     # Read and Load the configuration file
     try:
         with open(args.configfile, 'r') as f:
             dataConfig = json.load(f)
             
     except Exception as err:
-        print("Impossible to read or load JSON configuration file")
+        logger.critical("Impossible to read or load JSON configuration file : {err}. Check its path and content.".format(err=args.configfile))
         quit()
 
     # Load schema (into DiapOTB install)
@@ -86,13 +117,14 @@ if __name__ == "__main__":
                 with open(schema_S1SM, "r") as sch:
                     dataSchema = json.load(sch)
             except Exception as err:
-                print("Impossible to read or load JSON schema file")
+                logger.critical("Impossible to read or load JSON configuration file : {err}. Check its path and content.".format(err=schema_S1SM))
                 quit()
                     
             # Check Json file
             jsonIsValid = validate_json(dataConfig, dataSchema)
 
             if not jsonIsValid :
+                logger.critical("Error, provided config file does not match requirements")
                 quit()
 
     # Get dictionaries
@@ -140,20 +172,19 @@ if __name__ == "__main__":
     ml_geoGrid_range = ml_range
     ml_geoGrid_azimut = ml_azimut
     gain_interfero = dict_DInSAR['parameter']['Interferogram_gain']
-
+    
     if (geoGrid_threshold < 0) or (geoGrid_threshold > 1) :
-        print("Wrong Threshold for fine deformation grid")
-
+        logger.critical("Error, Wrong Threshold for fine deformation grid")
 
     # Check if images exist
     if not os.path.exists(master_Image) :
-        print(master_Image + " does not exists")
+        logger.critical("{img} does not exist. Check its path.".format(img=master_Image))
         quit()
     if not os.path.exists(slave_Image) :
-        print(slave_Image + " does not exists")
+        logger.critical("{img} does not exist. Check its path.".format(img=slave_Image))
         quit()
     if not os.path.exists(dem) :
-        print(dem + " does not exists")
+        logger.critical("{img} does not exist. Check its path.".format(img=dem))
         quit()
     if not os.path.exists(output_dir):
         print("The output directory does not exist and will be created")
@@ -161,6 +192,60 @@ if __name__ == "__main__":
     else :
         print("The output directory exists. Some files can be overwritten")
 
+
+    # File handler for the logger
+    # Create file handler which logs even info messages (used as stdout redirection)
+    file_handler = logging.FileHandler(os.path.join(output_dir, 'info.log'), 'a')
+    file_handler.setLevel(logging.INFO)
+    file_handler.setFormatter(LogFormatter)
+
+    # Add Handlers
+    logger.addHandler(file_handler)
+
+    # Redirect stdout and stderr to logger 
+    s1 = StreamToLogger(logger, logging.INFO)
+    stdout_saveWrite = sys.stdout.write # Save stdout.write to print some info into the console
+    stdout_saveFlush = sys.stdout.flush # Save stdout.flush to print some info into the console
+    sys.stdout.write = s1.write # Replace stdout.write by our StreamToLogger 
+    sys.stdout.flush = s1.flush # Replace stdout.flush by our StreamToLogger
+    stdout_save = s1 # Different object
+    stdout_save.write = stdout_saveWrite # Restore stdout.write into stdout_save
+    stdout_save.flush = stdout_saveFlush # Restore stdout.write into stdout_save
+
+    # Recap of input parameter into info.log
+    logger.info("########### Input Parameters for the current execution ############## ")
+    logger.info(" Pre_Processing : ")
+    logger.info("ml_range : {param}".format(param=ml_range))
+    logger.info("ml_azimut : {param}".format(param=ml_azimut))
+    logger.info("ml_gain : {param}".format(param=ml_gain))
+    logger.info("dop_file : {param}".format(param=dop_file))
+
+    # Metadata_Correction
+    logger.info(" Metadata_Correction : ")
+    logger.info("activateMetadataCorrection : {param}".format(param=activateMetadataCorrection))
+    if activateMetadataCorrection :
+        logger.info("ml_simu_range : {param}".format(param=ml_simu_range))
+        logger.info("ml_simu_azimut : {param}".format(param=ml_simu_azimut))
+        logger.info("ml_simu_gain : {param}".format(param=ml_simu_gain))
+        logger.info("ml_correlSimu_range : {param}".format(param=ml_correlSimu_range))
+        logger.info("ml_correlSimu_azimut : {param}".format(param=ml_correlSimu_azimut))
+        logger.info("correlSimu_gridstep_range : {param}".format(param=correlSimu_gridstep_range))
+        logger.info("correlSimu_gridstep_azimut : {param}".format(param=correlSimu_gridstep_azimut))
+        logger.info("fine_metadata_file : {param}".format(param=fine_metadata_file))
+
+    # DIn_SAR
+    logger.info(" DIn_SAR : ")
+    logger.info("geoGrid_gridstep_range : {param}".format(param=geoGrid_gridstep_range))
+    logger.info("geoGrid_gridstep_azimut : {param}".format(param=geoGrid_gridstep_azimut))
+    logger.info("geoGrid_threshold : {param}".format(param=geoGrid_threshold))
+    logger.info("geoGrid_gap : {param}".format(param=geoGrid_gap))
+    logger.info("ml_geoGrid_range : {param}".format(param=ml_geoGrid_range))
+    logger.info("ml_geoGrid_azimut : {param}".format(param=ml_geoGrid_azimut))
+    logger.info("gain_interfero : {param}".format(param=gain_interfero))
+    
+
+    logger.info("########### Input Images for the current execution ############## ")
+        
     master_Image_base = os.path.basename(master_Image)
     slave_Image_base = os.path.basename(slave_Image)
 
@@ -168,26 +253,27 @@ if __name__ == "__main__":
     master_ext = master_Image.split(".")[-1:]
     slave_ext = slave_Image.split(".")[-1:]
 
-    print ("master_ext = " + master_ext[0] + "\n")
-    print ("salve_ext = " + slave_ext[0] + "\n")
+    logger.info("master_ext = {ext}".format(ext=master_ext[0]))
+    logger.info("slave_ext = {ext}".format(ext=slave_ext[0]))
 
+    
     if master_ext[0] == "h5" :
         master_H5 = h5py.File(master_Image, 'r')
         lDataSet_master = list(master_H5.keys())
        
 
         if len(lDataSet_master) != 1 :
-            print("H5 input files does not contain the expected dataset \n")
+            logger.critical("Error, H5 input files does not contain the expected dataset")
             quit()
 
         if lDataSet_master[0] != "S01" :
-            print("H5 input files does not contain the expected dataset \n")
+            logger.critical("Error, H5 input files does not contain the expected dataset")
             quit()
 
         master_S01 = dict(master_H5['S01'])
         
         if not 'SBI' in master_S01:
-            print("H5 input files does not contain the expected dataset \n")
+            logger.critical("H5 input files does not contain the expected dataset")
             quit()
 
         # Change the name of master and slave image to read directly the //S01/SBI
@@ -201,27 +287,32 @@ if __name__ == "__main__":
         lDataSet_slave = list(slave_H5.keys())
 
         if len(lDataSet_slave) != 1 :
-            print("H5 input files does not contain the expected dataset \n")
+            logger.critical("H5 input files does not contain the expected dataset")
             quit()
 
         if lDataSet_slave[0] != "S01" :
-            print("H5 input files does not contain the expected dataset \n")
+            logger.critical("H5 input files does not contain the expected dataset")
             quit()
 
         slave_S01 = dict(slave_H5['S01'])
         
         if not 'SBI' in slave_S01 :
-            print("H5 input files does not contain the expected dataset \n")
+            logger.critical("H5 input files does not contain the expected dataset")
             quit()
         
         slave_Image = "HDF5:" + slave_Image + "://S01/SBI"
 
-    print("master_Image = " + master_Image + "\n") 
-    print("slave_Image = " + slave_Image + "\n") 
+    logger.info("master_Image = {img}".format(img=master_Image))
+    logger.info("slave_Image = {img}".format(img=slave_Image))
+    logger.info("dem : {param}".format(param=dem))
+
+    print("\n Beginning of DiapOTB processing \n", file=stdout_save)
+    logger.info("############ Beginning of DiapOTB processing ##############")
 
     ####################### Pre Processing Chain ##########################
     ######## SARDoppler Application #######
-    print("\n Doppler Application \n")
+    print("\n Doppler Application \n", file=stdout_save)
+    logger.info("Doppler Application")
     # Master
     dopFile = open(os.path.join(output_dir, dop_file), "w")
     dopFile.write("Doppler for master image : " + os.path.basename(master_Image_base)+ "\n")
@@ -244,7 +335,8 @@ if __name__ == "__main__":
 
 
     ####### SARMultiLook Application #######
-    print("\n MultiLook Application \n")
+    print("\n MultiLook Application \n", file=stdout_save)
+    logger.info("MultiLook Application")
     # Master
     master_Image_ML = os.path.splitext(master_Image_base)[0] + "_ml" + str(ml_azimut) + str(ml_range) + ".tif"
     appMultiLookMaster = otb.Registry.CreateApplication("SARMultiLook")
@@ -273,7 +365,8 @@ if __name__ == "__main__":
     # ######################## Metadata Correction Chain #############################
     if activateMetadataCorrection :        
         ######## SARDEMToAmplitude Application (Simu_SAR step) #######
-        print("\n SARDEMToAmplitude Application \n")
+        print("\n SARDEMToAmplitude Application \n", file=stdout_save)
+        logger.info("SARDEMToAmplitude Application")
         amplitude_simu_image = os.path.splitext(master_Image_base)[0] + "_simuSAR" + "_ml" + str(ml_simu_azimut) + str(ml_simu_range) + ".tif"
         appDEMToAmplitude = otb.Registry.CreateApplication("SARDEMToAmplitude")
         appDEMToAmplitude.SetParameterString("insar", master_Image)
@@ -289,7 +382,8 @@ if __name__ == "__main__":
 
 
         ######## SARCorrelationGrid Application (Correl step) #######
-        print("\n SARCorrelationGrid Application \n")
+        print("\n SARCorrelationGrid Application \n", file=stdout_save)
+        logger.info("SARCorrelationGrid Application")
         correl_grid = "correl_simu" + "_gridstep" + str(correlSimu_gridstep_azimut) + str(correlSimu_gridstep_range) + ".tif"
         appCorGrid = otb.Registry.CreateApplication("SARCorrelationGrid")
         appCorGrid.SetParameterString("inmaster", os.path.join(output_dir, master_Image_ML))
@@ -306,7 +400,8 @@ if __name__ == "__main__":
 
 
         ######## SARFineMetadata Application (Correct_snrt step) #######
-        print("\n SARFineMetadata Application \n")
+        print("\n SARFineMetadata Application \n", file=stdout_save)
+        logger.info("SARFineMetadata Application")
         appFineMetadata = otb.Registry.CreateApplication("SARFineMetadata")
         appFineMetadata.SetParameterString("insar", master_Image)
         appFineMetadata.SetParameterString("ingrid", os.path.join(output_dir, correl_grid))
@@ -322,7 +417,8 @@ if __name__ == "__main__":
     
     ######################## DIn_SAR Chain #############################
     ######## SARDEMProjection Application #######
-    print("\n SARDEMProjection Application \n")
+    print("\n SARDEMProjection Application \n", file=stdout_save)
+    logger.info("SARDEMProjection Application")
     # Master
     demProj_Master = "demProj_Master.tif"
     appDEMProjectionMaster = otb.Registry.CreateApplication("SARDEMProjection")
@@ -349,7 +445,8 @@ if __name__ == "__main__":
 
 
     ######## SARFineDeformationGrid Application (geo_grid step) #######
-    print("\n SARFineDeformationGrid Application \n")
+    print("\n SARFineDeformationGrid Application \n", file=stdout_save)
+    logger.info("SARFineDeformationGrid Application")
     fine_grid = "fineDeformationGrid.tif"
     appFineDeformationGrid = otb.Registry.CreateApplication("SARFineDeformationGrid")
     appFineDeformationGrid.SetParameterString("indem", dem)
@@ -374,7 +471,8 @@ if __name__ == "__main__":
 
     
     ######## SARCoRegistration Application (changeo step) #######
-    print("\n SARCoRegistration Application \n")
+    print("\n SARCoRegistration Application \n", file=stdout_save)
+    logger.info("SARCoRegistration Application")
     slave_Image_CoRe = os.path.splitext(slave_Image_base)[0] + "_coregistrated.tif"
     appCoRegistration = otb.Registry.CreateApplication("SARCoRegistration")
     appCoRegistration.SetParameterString("insarmaster", master_Image)
@@ -393,6 +491,7 @@ if __name__ == "__main__":
     
     ######## SARCartesianMeanEstimation Application #######
     print("\n SARCartesianMeanEstimation Application \n")
+    logger.info("SARCartesianMeanEstimation Application")
     # Master
     master_cartesian_mean = "CartMeanMaster.tif"
     master_cartesianperline_mean = "CartMeanPerLineMaster.tif"
@@ -410,7 +509,8 @@ if __name__ == "__main__":
 
 
     ######## SARRobustInterferogram Application (interf step) #######
-    print("\n SARRobustInterferogram Application \n")
+    print("\n SARRobustInterferogram Application \n", file=stdout_save)
+    logger.info("SARRobustInterferogram Application")
     interferogram = "interferogram.tif"
     appInterferogram = otb.Registry.CreateApplication("SARRobustInterferogram")
     appInterferogram.SetParameterString("insarmaster", master_Image)
@@ -426,3 +526,7 @@ if __name__ == "__main__":
     appInterferogram.SetParameterString("ram", "4000")
     appInterferogram.SetParameterString("out", os.path.join(output_dir, interferogram))
     appInterferogram.ExecuteAndWriteOutput()
+
+
+    print("\n End of DiapOTB processing \n", file=stdout_save)
+    logger.info("############# End of DiapOTB processing ##############")
diff --git a/python_src/diapOTB_S1IW.py b/python_src/diapOTB_S1IW.py
index 0dcf6ed..d5a8364 100644
--- a/python_src/diapOTB_S1IW.py
+++ b/python_src/diapOTB_S1IW.py
@@ -39,7 +39,23 @@ import re
 
 import otbApplication as otb
 
-logger = logging.getLogger(__name__)
+# Streamer to our log file
+class StreamToLogger(object):
+    """
+    Fake file-like stream object that redirects writes to a logger instance.
+    """
+    def __init__(self, logger, log_level=logging.INFO):
+        self.logger = logger
+        self.log_level = log_level
+
+    def write(self, buf):
+        for line in buf.rstrip().splitlines():
+            self.logger.log(self.log_level, line.rstrip())
+
+    def flush(self):
+        for handler in self.logger.handlers:
+            handler.flush()
+
 
 def validate_json(json, schema):
     try:
@@ -105,13 +121,26 @@ if __name__ == "__main__":
     args = parser.parse_args()
     print(args.configfile)
 
+    # Logger initialization
+    logger = logging.getLogger(__name__)
+    logger.setLevel(logging.INFO)
+    
+    LogFormatter = logging.Formatter('%(filename)s :: %(levelname)s :: %(message)s')
+
+    # Create console handler with a high log level (warning level)
+    stream_handler = logging.StreamHandler()
+    stream_handler.setLevel(logging.WARNING)
+
+    # Add Handlers
+    logger.addHandler(stream_handler)
+
     # Read and Load the configuration file
     try:
         with open(args.configfile, 'r') as f:
             dataConfig = json.load(f)
             
     except Exception as err:
-        print("Impossible to read or load JSON configuration file")
+        logger.critical("Impossible to read or load JSON configuration file : {err}. Check its path and content.".format(err=args.configfile))
         quit()
 
     # Load schema (into DiapOTB install)
@@ -125,13 +154,14 @@ if __name__ == "__main__":
                 with open(schema_S1IW, "r") as sch:
                     dataSchema = json.load(sch)
             except Exception as err:
-                print("Impossible to read or load JSON schema file")
+                logger.critical("Impossible to read or load JSON configuration file : {err}. Check its path and content.".format(err=schema_S1SM))
                 quit()
 
             # Check Json file
             jsonIsValid = validate_json(dataConfig, dataSchema)
 
             if not jsonIsValid :
+                logger.critical("Error, provided config file does not match requirements")
                 quit()
 
     # Get dictionaries
@@ -176,24 +206,22 @@ if __name__ == "__main__":
     else :
         esd_AutoMode = True
         esd_NbIter = 10 # 10 iterations maximum for automatic mode
-
-    print("esd_NbIter = " + str(esd_NbIter))
-    print("esd_AutoMode = " + str(esd_AutoMode))
+   
 
     # Check Threshold
     if (geoGrid_threshold < 0) or (geoGrid_threshold > 1) :
-        print("Wrong Threshold for fine deformation grid")
+        logger.critical("Error, Wrong Threshold for fine deformation grid")
         geoGrid_threshold = 0.3
 
     # Check if images/dem exist
     if not os.path.exists(master_Image) :
-        print(master_Image + " does not exists")
+        logger.critical("{img} does not exist. Check its path.".format(img=master_Image))
         quit()
     if not os.path.exists(slave_Image) :
-        print(slave_Image + " does not exists")
+        logger.critical("{img} does not exist. Check its path.".format(img=slave_Image))
         quit()
     if not os.path.exists(dem) :
-        print(dem + " does not exists")
+        logger.critical("{img} does not exist. Check its path.".format(img=dem))
         quit()
     if not os.path.exists(output_dir):
         print("The output directory does not exist and will be created")
@@ -201,6 +229,51 @@ if __name__ == "__main__":
     else :
         print("The output directory exists. Some files can be overwritten")
 
+
+    # File handler for the logger
+    # Create file handler which logs even info messages (used as stdout redirection)
+    file_handler = logging.FileHandler(os.path.join(output_dir, 'info.log'), 'a')
+    file_handler.setLevel(logging.INFO)
+    file_handler.setFormatter(LogFormatter)
+
+    # Add Handlers
+    logger.addHandler(file_handler)
+
+    # Redirect stdout and stderr to logger 
+    s1 = StreamToLogger(logger, logging.INFO)
+    stdout_saveWrite = sys.stdout.write # Save stdout.write to print some info into the console
+    stdout_saveFlush = sys.stdout.flush # Save stdout.flush to print some info into the console
+    sys.stdout.write = s1.write # Replace stdout.write by our StreamToLogger 
+    sys.stdout.flush = s1.flush # Replace stdout.flush by our StreamToLogger
+    stdout_save = s1 # Different object
+    stdout_save.write = stdout_saveWrite # Restore stdout.write into stdout_save
+    stdout_save.flush = stdout_saveFlush # Restore stdout.write into stdout_save
+
+     # Recap of input parameter into info.log
+    logger.info("########### Input Parameters for the current execution ############## ")
+    logger.info(" Pre_Processing : ")
+    logger.info("ml_range : {param}".format(param=ml_range))
+    logger.info("ml_azimut : {param}".format(param=ml_azimut))
+    logger.info("ml_gain : {param}".format(param=ml_gain))
+    logger.info("dop_file : {param}".format(param=dop_file))
+
+    # DIn_SAR
+    logger.info(" DIn_SAR : ")
+    logger.info("geoGrid_gridstep_range : {param}".format(param=geoGrid_gridstep_range))
+    logger.info("geoGrid_gridstep_azimut : {param}".format(param=geoGrid_gridstep_azimut))
+    logger.info("geoGrid_threshold : {param}".format(param=geoGrid_threshold))
+    logger.info("geoGrid_gap : {param}".format(param=geoGrid_gap))
+    logger.info("ml_geoGrid_range : {param}".format(param=ml_geoGrid_range))
+    logger.info("ml_geoGrid_azimut : {param}".format(param=ml_geoGrid_azimut))
+    logger.info("gain_interfero : {param}".format(param=gain_interfero))
+    logger.info("esd_AutoMode : {param}".format(param=esd_AutoMode))
+    logger.info("esd_NbIter : {param}".format(param=esd_NbIter))
+
+    logger.info("########### Input Images for the current execution ############## ")
+    logger.info("master_Image : {param}".format(param=master_Image))
+    logger.info("slave_Image : {param}".format(param=slave_Image))
+    logger.info("dem : {param}".format(param=dem))
+
     # check Burst index      
     master_Image_base = os.path.basename(master_Image)
     slave_Image_base = os.path.basename(slave_Image)
@@ -227,7 +300,7 @@ if __name__ == "__main__":
     
     # Check header version
     if int(dictKWLMaster['header.version']) < 3 or int(dictKWLSlave['header.version']) < 3 :
-        print ("Upgrade your geom file")
+        logger.critical("Upgrade your geom file")
         quit()
 
     # Get information about DEM (spacing, size ..)
@@ -246,7 +319,7 @@ if __name__ == "__main__":
     
     if estimatedGroundSpacingXDEM > 40. or estimatedGroundSpacingYDEM > 40. :
         advantage = "correlation" # Correlation if resolution > 40 m
-        print("Resolution of the input DEM is inferior to 40 meters : A correlation will be used to correct all deformation grids")
+        logger.warning("Resolution of the input DEM is inferior to 40 meters : A correlation will be used to correct all deformation grids")
         
         
     # Selection of bursts
@@ -269,11 +342,11 @@ if __name__ == "__main__":
                     firstBurst = min(burstList)
                     lastBurst = max(burstList)
     except Exception as err:
-        print("Wrong burst index")
+        logger.critical("Wrong burst index")
         quit()
                 
     if minNbBurst < firstBurst or minNbBurst < lastBurst or lastBurst < 0 or firstBurst < 0 :
-        print ("Wrong burst index")
+        logger.critical("Wrong burst index")
         quit()
    
     validBurstMaster = [] 
@@ -282,7 +355,7 @@ if __name__ == "__main__":
     selectBurst(dictKWLMaster, dictKWLSlave, firstBurst, lastBurst, nbBurstSlave, validBurstMaster, validBurstSlave)
 
     if len(validBurstMaster) == 0 or len(validBurstSlave) == 0 :
-        print("Wrong burst index (slave index does not match with master index)")
+        logger.critical("Wrong burst index (slave index does not match with master index)")
         quit()
 
     # Update firstBurst and lastBurst with selected Burst for master image
@@ -294,6 +367,10 @@ if __name__ == "__main__":
     for burstId in range(validBurstMaster[0], validBurstMaster[len(validBurstMaster)-1]+1):
         if not os.path.exists(os.path.join(output_dir, "burst" + str(burstId))):
             os.makedirs(os.path.join(output_dir, "burst" + str(burstId)))
+
+
+    print("\n Beginning of DiapOTB processing (S1 IW mode) \n", file=stdout_save)
+    logger.info("############ Beginning of DiapOTB processing  (S1 IW mode) ##############")
                         
     ####################### Pre Processing Chain ##########################
     # Initialisation of doppler file 
@@ -301,7 +378,8 @@ if __name__ == "__main__":
     dopFile.close()
 
     # Master
-    print("\n Master Pre-Processing \n")
+    print("\n Master Pre-Processing \n", file=stdout_save)
+    logger.info("Master Pre-Processing")
 
     dop0Master = []
     
@@ -309,12 +387,14 @@ if __name__ == "__main__":
         #burstId = id_loop + firstBurst
         burstId = validBurstMaster[id_loop]
    
-        print("\n BurstId = " + str(burstId) + "\n")
+        print("\n BurstId = " + str(burstId) + "\n", file=stdout_save)
+        logger.info("BurstId = {ind}".format(ind=burstId))
 
         burst_dir = os.path.join(output_dir, "burst" + str(burstId))
 
         ######## SARBurstExtraction Application #######
-        print("\n Burst Extraction Application \n")
+        print("\n Burst Extraction Application \n", file=stdout_save)
+        logger.info("Burst Extraction Application")
         burstM = os.path.splitext(master_Image_base)[0] + "_burst" + str(burstId) + ".tif"
         appBurstExtractionMaster = otb.Registry.CreateApplication("SARBurstExtraction")
         appBurstExtractionMaster.SetParameterString("in", master_Image)
@@ -325,7 +405,8 @@ if __name__ == "__main__":
         appBurstExtractionMaster.ExecuteAndWriteOutput()
 
         ######## SARDeramp Application #######
-        # print("\n Deramping Application \n")
+        print("\n Deramping Application \n", file=stdout_save)
+        logger.info("Deramping Application")
         burstDerampM = os.path.splitext(master_Image_base)[0] + "_burst" + str(burstId) + "_deramp" + ".tif"
         appDerampMaster = otb.Registry.CreateApplication("SARDeramp")
         appDerampMaster.SetParameterString("in", os.path.join(burst_dir, burstM))
@@ -334,7 +415,8 @@ if __name__ == "__main__":
         appDerampMaster.ExecuteAndWriteOutput()
         
         ######## SARDoppler Application #######
-        print("\n Doppler Application \n")
+        print("\n Doppler Application \n", file=stdout_save)
+        logger.info("Doppler Application")
         dopFile = open(os.path.join(output_dir, dop_file), "a")
         dopFile.write("Doppler for master image : " + os.path.basename(master_Image_base)+ " for burst_index = " + str(burstId) + "\n")
         dopFile.close()
@@ -347,7 +429,8 @@ if __name__ == "__main__":
         dop0Master.append(appDoppler0Master.GetParameterFloat('doppler0'))
 
         ####### SARMultiLook Application #######
-        print("\n MultiLook Application \n")
+        print("\n MultiLook Application \n", file=stdout_save)
+        logger.info("MultiLook Application")
         master_Image_ML = os.path.splitext(master_Image_base)[0] + "_burst" + str(burstId) + "_ml" + str(ml_azimut) + str(ml_range) + ".tif"
         appMultiLookMaster = otb.Registry.CreateApplication("SARMultiLook")
         appMultiLookMaster.SetParameterString("incomplex", os.path.join(burst_dir, burstDerampM))
@@ -359,7 +442,8 @@ if __name__ == "__main__":
         appMultiLookMaster.ExecuteAndWriteOutput()
 
     # Slave
-    print("\n Slave Pre-Processing \n")
+    print("\n Slave Pre-Processing \n", file=stdout_save)
+    logger.info("Slave Pre-Processing")
 
     dop0Slave = []
   
@@ -368,12 +452,15 @@ if __name__ == "__main__":
         burstId = validBurstMaster[id_loop]
         burstId_slave = validBurstSlave[id_loop]
 
-        print("\n BurstId = " + str(burstId_slave) + "\n")
+        print("\n BurstId = " + str(burstId) + "\n", file=stdout_save)
+        logger.info("BurstId = {ind}".format(ind=burstId))
+
 
         burst_dir = os.path.join(output_dir, "burst" + str(burstId))
 
         ######## SARBurstExtraction Application #######
-        print("\n Burst Extraction Application \n")
+        print("\n Burst Extraction Application \n", file=stdout_save)
+        logger.info("Burst Extraction Application")
         burstS = os.path.splitext(slave_Image_base)[0] + "_burst" + str(burstId_slave) + ".tif"
         appBurstExtractionSlave = otb.Registry.CreateApplication("SARBurstExtraction")
         appBurstExtractionSlave.SetParameterString("in", slave_Image)
@@ -384,7 +471,8 @@ if __name__ == "__main__":
         appBurstExtractionSlave.ExecuteAndWriteOutput()
     
         ######## SARDeramp Application #######
-        # print("\n Deramping Application \n")
+        print("\n Deramping Application \n", file=stdout_save)
+        logger.info("Deramping Application")
         burstDerampS = os.path.splitext(slave_Image_base)[0] + "_burst" + str(burstId_slave) + "_deramp" + ".tif"
         appDerampSlave = otb.Registry.CreateApplication("SARDeramp")
         appDerampSlave.SetParameterString("in", os.path.join(burst_dir, burstS))
@@ -393,7 +481,8 @@ if __name__ == "__main__":
         appDerampSlave.ExecuteAndWriteOutput()
         
         ######## SARDoppler Application #######
-        print("\n Doppler Application \n")
+        print("\n Doppler Application \n", file=stdout_save)
+        logger.info("Doppler Application")
         dopFile = open(os.path.join(output_dir, dop_file), "a")
         dopFile.write("Doppler for slave image : " + os.path.basename(slave_Image_base) + " for burst_index = " + str(burstId_slave) + "\n")
         dopFile.close()
@@ -406,7 +495,8 @@ if __name__ == "__main__":
         dop0Slave.append(appDoppler0Slave.GetParameterFloat('doppler0'))
 
         ####### SARMultiLook Application #######
-        print("\n MultiLook Application \n")
+        print("\n MultiLook Application \n", file=stdout_save)
+        logger.info("MultiLook Application")
         slave_Image_ML = os.path.splitext(slave_Image_base)[0] + "_burst" + str(burstId_slave) + "_ml" + str(ml_azimut) + str(ml_range) + ".tif"
         appMultiLookSlave = otb.Registry.CreateApplication("SARMultiLook")
         appMultiLookSlave.SetParameterString("incomplex", os.path.join(burst_dir, burstDerampS))
@@ -420,7 +510,8 @@ if __name__ == "__main__":
 
     ######################### Ground Chain #############################
     # Master
-    print("\n Master Ground chain \n")
+    print("\n Master Ground chain \n", file=stdout_save)
+    logger.info("Master Ground Application")
 
     gainMaster = []
     directionDEMMaster = []
@@ -429,7 +520,8 @@ if __name__ == "__main__":
         #burstId = id_loop + firstBurst
         burstId = validBurstMaster[id_loop]
         
-        print("\n BurstId = " + str(burstId) + "\n")
+        print("\n BurstId = " + str(burstId) + "\n", file=stdout_save)
+        logger.info("BurstId = {ind}".format(ind=burstId))
 
         burst_dir = os.path.join(output_dir, "burst" + str(burstId))
 
@@ -437,7 +529,8 @@ if __name__ == "__main__":
         
     
         ######## SARDEMProjection Application #######
-        print("\n SARDEMProjection Application \n")
+        print("\n SARDEMProjection Application \n", file=stdout_save)
+        logger.info("SARDEMProjection Application")
         demProj_Master = "demProj" +  "_burst" + str(burstId) +"_Master.tif"
         appDEMProjectionMaster = otb.Registry.CreateApplication("SARDEMProjection")
         appDEMProjectionMaster.SetParameterString("insar", os.path.join(burst_dir, burstDerampM))
@@ -452,7 +545,8 @@ if __name__ == "__main__":
         directionDEMMaster.append([appDEMProjectionMaster.GetParameterInt('directiontoscandemc'), appDEMProjectionMaster.GetParameterInt('directiontoscandeml')])
 
         ######### SARCartesianMeanEstimation Application #######
-        print("\n SARCartesianMeanEstimation Application \n")
+        print("\n SARCartesianMeanEstimation Application \n", file=stdout_save)
+        logger.info("SARCartesianMeanEstimation Application")
         master_cartesian_mean = "CartMeanMaster" +  "_burst" + str(burstId) + ".tif"
         appCartMeanMaster = otb.Registry.CreateApplication("SARCartesianMeanEstimation")
         appCartMeanMaster.SetParameterString("insar", os.path.join(burst_dir, burstDerampM))
@@ -470,7 +564,8 @@ if __name__ == "__main__":
     print (directionDEMMaster)
 
     # Slave
-    print("\n Slave Ground chain \n")
+    print("\n Slave Ground chain \n", file=stdout_save)
+    logger.info("Slave Ground Application")
 
     gainSlave = []
     directionDEMSlave = []
@@ -480,12 +575,15 @@ if __name__ == "__main__":
         burstId = validBurstMaster[id_loop]
         burstId_slave = validBurstSlave[id_loop]
 
-        print("\n BurstId = " + str(burstId_slave) + "\n")
+        print("\n BurstId = " + str(burstId) + "\n", file=stdout_save)
+        logger.info("BurstId = {ind}".format(ind=burstId))
 
         burst_dir = os.path.join(output_dir, "burst" + str(burstId))
 
         burstDerampS = os.path.splitext(slave_Image_base)[0] + "_burst" + str(burstId_slave) + "_deramp" + ".tif"
-        
+
+        print("\n SARDEMProjection Application \n", file=stdout_save)
+        logger.info("SARDEMProjection Application")
         demProj_Slave = "demProj" +  "_burst" + str(burstId_slave) + "_Slave.tif"
         appDEMProjectionSlave = otb.Registry.CreateApplication("SARDEMProjection")
         appDEMProjectionSlave.SetParameterString("insar", os.path.join(burst_dir, burstDerampS))
@@ -498,7 +596,8 @@ if __name__ == "__main__":
         
     
     ######################## DIn_SAR Chain #############################
-    print("\n DIn_SAR chain \n")
+    print("\n DIn_SAR chain \n", file=stdout_save)
+    logger.info("DIn_SAR chain")
 
     counter = 0
     list_of_Interferograms = []
@@ -509,7 +608,8 @@ if __name__ == "__main__":
         burstId = validBurstMaster[id_loop]
         burstId_slave = validBurstSlave[id_loop]
         
-        print("\n BurstId = " + str(burstId) + "\n")
+        print("\n BurstId = " + str(burstId) + "\n", file=stdout_save)
+        logger.info("BurstId = {ind}".format(ind=burstId))
 
         burst_dir = os.path.join(output_dir, "burst" + str(burstId))
         
@@ -530,7 +630,8 @@ if __name__ == "__main__":
 
         ######## Step 1 : SARFineDeformationGrid #######
         ######## SARFineDeformationGrid Application (geo_grid step) #######
-        print("\n SARFineDeformationGrid Application \n")
+        print("\n SARFineDeformationGrid Application \n", file=stdout_save)
+        logger.info("SARFineDeformationGrid Application")
         fine_grid = "fineDeformationGrid"+ "_burst" + str(burstId) + ".tif"
         appFineDeformationGrid = otb.Registry.CreateApplication("SARFineDeformationGrid")
         appFineDeformationGrid.SetParameterString("indem", dem)
@@ -555,7 +656,8 @@ if __name__ == "__main__":
         
         ####### Step 3 : SARCoRegistration + SARDeramp + SARRobustInterferogram #######
         ####### SARCoRegistration Application (changeo step) #######
-        print("\n SARCoRegistration Application \n")
+        print("\n SARCoRegistration Application \n", file=stdout_save)
+        logger.info("SARCoRegistration Application")
         slave_Image_CoRe = os.path.splitext(slave_Image_base)[0] + "_burst" + str(burstId) + "_coregistrated.tif"
         appCoRegistration = otb.Registry.CreateApplication("SARCoRegistration")
         appCoRegistration.SetParameterString("insarmaster", os.path.join(burst_dir, burstDerampM))
@@ -572,7 +674,8 @@ if __name__ == "__main__":
         appCoRegistration.ExecuteAndWriteOutput()
 
         ######## SARDeramp Application (reramp mode) #######
-        print("\n Deramping Application \n")
+        print("\n Deramping Application \n", file=stdout_save)
+        logger.info("Deramping Application")
         # Slave (CoRegistrated)
         burstCoReRerampS = os.path.splitext(slave_Image_base)[0] + "_burst" + str(burstId) + "_coregistrated_reramp" + ".tif"
         appDerampSlave = otb.Registry.CreateApplication("SARDeramp")
@@ -588,7 +691,8 @@ if __name__ == "__main__":
         appDerampSlave.ExecuteAndWriteOutput()
 
         ######## SARRobustInterferogram Application (interf step) #######
-        print("\n SARRobustInterferogram Application \n")
+        print("\n SARRobustInterferogram Application \n", file=stdout_save)
+        logger.info("SARRobustInterferogram Application")
         interferogram_path = os.path.join(burst_dir, "interferogram" + "_burst" + str(burstId) + ".tif")
         
         if esd_NbIter > 0 :
@@ -621,6 +725,9 @@ if __name__ == "__main__":
 
 
     ######## Step 4 : ESD Loop (SARESD + SARGridOffset + Step 3) #######
+    print ("Beginning of ESD Loop", file=stdout_save)
+    logger.info("Beginning of ESD Loop")
+    
     if esd_NbIter > 0 :
         
         azimut_shift_esd = []
@@ -628,6 +735,9 @@ if __name__ == "__main__":
         
         for iter_esd in range(1, esd_NbIter+1) :
 
+            print ("Iteration number = {number}".format(number=iter_esd), file=stdout_save)
+            logger.info("Iteration number = {number}".format(number=iter_esd))
+
             # Clear all azimut shifts
             azimut_shift_esd[:] = []
 
@@ -635,7 +745,8 @@ if __name__ == "__main__":
                 #burstId = id_loop + firstBurst
                 burstId = validBurstMaster[id_loop]
             
-                print("\n BurstId = " + str(burstId) + "\n")
+                print("\n BurstId = " + str(burstId) + "\n", file=stdout_save)
+                logger.info("BurstId = {ind}".format(ind=burstId))
                 
                 # Paths
                 burst_dir = os.path.join(output_dir, "burst" + str(burstId))
@@ -645,7 +756,8 @@ if __name__ == "__main__":
                 # Check number of burst index (not SARESD for lastBurst)
                 if burstId < lastBurst :
                     ######## SARESD Application #######
-                    print("\n ESD Application \n")
+                    print("\n ESD Application \n", file=stdout_save)
+                    logger.info("Beginning of ESD Loop")
                     appESD = otb.Registry.CreateApplication("SARESD")
                     appESD.SetParameterString("ininterfup", list_of_Interferograms[burstId-firstBurst])
                     appESD.SetParameterString("ininterflow", list_of_Interferograms[burstId-firstBurst+1])
@@ -695,7 +807,8 @@ if __name__ == "__main__":
                 
                 # Offset of deformation grid with the azimut shift
                 ######## SARGridOffset Application #######
-                print("\n GridOffset Application \n")
+                print("\n GridOffset Application \n", file=stdout_save)
+                logger.info("GridOffset Application")
                 appGridOff = otb.Registry.CreateApplication("SARGridOffset")
                 appGridOff.SetParameterString("ingrid", list_of_Grids[burstId-firstBurst])
                 appGridOff.SetParameterFloat("offsetran", 0.)
@@ -706,7 +819,8 @@ if __name__ == "__main__":
 
                 ######## Step 3 : SARCoRegistration + SARDeramp + SARRobustInterferogram #######
                 ######## SARCoRegistration Application (changeo step) #######
-                print("\n SARCoRegistration Application \n")
+                print("\n SARCoRegistration Application \n", file=stdout_save)
+                logger.info("SARCoRegistration Application")
                 slave_Image_CoRe = os.path.splitext(slave_Image_base)[0] + "_burst" + str(burstId) + "_coregistrated.tif"
                 appCoRegistration = otb.Registry.CreateApplication("SARCoRegistration")
                 appCoRegistration.SetParameterString("insarmaster", os.path.join(burst_dir, burstDerampM))
@@ -723,7 +837,8 @@ if __name__ == "__main__":
                 appCoRegistration.Execute()
             
                 ######## SARDeramp Application (reramp mode) #######
-                print("\n Deramping Application \n")
+                print("\n Deramping Application \n", file=stdout_save)
+                logger.info("Deramping Application")
                 # Slave (CoRegistrated)
                 burstCoReRerampS = os.path.splitext(slave_Image_base)[0] + "_burst" + str(burstId) + "_coregistrated_reramp" + ".tif"
                 appDerampSlave = otb.Registry.CreateApplication("SARDeramp")
@@ -740,7 +855,8 @@ if __name__ == "__main__":
                 appDerampSlave.Execute()
                 
                 ######## SARRobustInterferogram Application (interf step) #######
-                print("\n SARRobustInterferogram Application \n")
+                print("\n SARRobustInterferogram Application \n", file=stdout_save)
+                logger.info("SARRobustInterferogram Application")
                 interferogram_path = os.path.join(esd_dir, "interferogram" + "_burst" + str(burstId) + "_iter" + str(iter_esd) + ".tif")
                 
                 appInterferogram = otb.Registry.CreateApplication("SARRobustInterferogram")
@@ -773,7 +889,8 @@ if __name__ == "__main__":
         
     ######## Step 5 : SARConcatenateBursts #######
     ######### SARConcatenateBursts (for interferograms) #########
-    print("\n SARConcatenateBursts Application (for interferograms) \n")
+    print("\n SARConcatenateBursts Application (for interferograms) \n", file=stdout_save)
+    logger.info("SARConcatenateBursts Application")
     interferogram_swath = "interferogram_swath.tif"
     appCon = otb.Registry.CreateApplication("SARConcatenateBursts")
     appCon.SetParameterStringList("il", list_of_Interferograms)
@@ -783,3 +900,6 @@ if __name__ == "__main__":
     appCon.SetParameterString("ram", "4000")
     appCon.ExecuteAndWriteOutput()
     
+
+    print("\n End of DiapOTB processing (S1 IW mode) \n", file=stdout_save)
+    logger.info("############ End of DiapOTB processing  (S1 IW mode) ##############")
-- 
GitLab