! ! CRTM_LifeCycle ! ! Module containing CRTM life cycle functions to initialize and destroy ! the CRTM space. ! ! Written by: Paul van Delst, 21-May-2004 ! paul.vandelst@noaa.gov ! MODULE CRTM_LifeCycle ! ----------------- ! Environment setup ! ----------------- ! Module usage USE Message_Handler USE CRTM_SpcCoeff USE CRTM_TauCoeff USE CRTM_AerosolCoeff , ONLY: CRTM_AerosolCoeff_Load, & CRTM_AerosolCoeff_Destroy USE CRTM_CloudCoeff , ONLY: CRTM_CloudCoeff_Load, & CRTM_CloudCoeff_Destroy USE CRTM_EmisCoeff USE CRTM_ChannelInfo_Define, ONLY: CRTM_ChannelInfo_type, & CRTM_ChannelInfo_Associated, & CRTM_ChannelInfo_Destroy, & CRTM_ChannelInfo_Create ! Disable all implicit typing IMPLICIT NONE ! ------------ ! Visibilities ! ------------ ! Everything private by default PRIVATE ! Public procedures PUBLIC :: CRTM_Init PUBLIC :: CRTM_Destroy PUBLIC :: CRTM_LifeCycleVersion ! ----------------- ! Module parameters ! ----------------- CHARACTER(*), PARAMETER :: MODULE_VERSION_ID = & '$Id: CRTM_LifeCycle.f90 22707 2012-11-21 21:09:10Z paul.vandelst@noaa.gov $' ! String lengths INTEGER, PARAMETER :: ML = 256 ! Error message length INTEGER, PARAMETER :: SL = 2000 ! Maximum length for path+filenames CONTAINS !------------------------------------------------------------------------------ !:sdoc+: ! ! NAME: ! CRTM_Init ! ! PURPOSE: ! Function to initialise the CRTM. ! ! CALLING SEQUENCE: ! Error_Status = CRTM_Init( Sensor_ID , & ! ChannelInfo , & ! CloudCoeff_File = CloudCoeff_File , & ! AerosolCoeff_File = AerosolCoeff_File, & ! EmisCoeff_File = EmisCoeff_File , & ! File_Path = File_Path , & ! Load_CloudCoeff = Load_CloudCoeff , & ! Load_AerosolCoeff = Load_AerosolCoeff, & ! Quiet = Quiet , & ! Process_ID = Process_ID , & ! Output_Process_ID = Output_Process_ID ) ! ! INPUTS: ! Sensor_ID: List of the sensor IDs (e.g. hirs3_n17, amsua_n18, ! ssmis_f16, etc) with which the CRTM is to be ! initialised. These sensor ids are used to construct ! the sensor specific SpcCoeff and TauCoeff filenames ! containing the necessary coefficient data, i.e. ! <Sensor_ID>.SpcCoeff.bin ! and ! <Sensor_ID>.TauCoeff.bin ! for each sensor Id in the list. ! UNITS: N/A ! TYPE: CHARACTER(*) ! DIMENSION: Rank-1 (n_Sensors) ! ATTRIBUTES: INTENT(IN), OPTIONAL ! ! OUTPUTS: ! ChannelInfo: ChannelInfo structure array populated based on ! the contents of the coefficient files and the ! user inputs. ! UNITS: N/A ! TYPE: CRTM_ChannelInfo_type ! DIMENSION: Same as input Sensor_Id argument ! ATTRIBUTES: INTENT(OUT) ! ! OPTIONAL INPUTS: ! CloudCoeff_File: Name of the CRTM Binary format CloudCoeff file ! containing the scattering coefficient data. If not ! specified the default filename is "CloudCoeff.bin". ! UNITS: N/A ! TYPE: CHARACTER(*) ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN), OPTIONAL ! ! AerosolCoeff_File: Name of the CRTM Binary format AerosolCoeff file ! containing the aerosol absorption and scattering ! coefficient data. If not specified the default ! filename is "AerosolCoeff.bin". ! UNITS: N/A ! TYPE: CHARACTER(*) ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN), OPTIONAL ! ! EmisCoeff_File: Name of the CRTM Binary format EmisCoeff file ! containing the IRSSEM coefficient data. If not ! specified the default filename is "EmisCoeff.bin". ! UNITS: N/A ! TYPE: CHARACTER(*) ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN), OPTIONAL ! ! File_Path: Character string specifying a file path for the ! input data files. If not specified, the current ! directory is the default. ! UNITS: N/A ! TYPE: CHARACTER(*) ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN), OPTIONAL ! ! Load_CloudCoeff: Set this logical argument for not loading the CloudCoeff data ! to save memory space under the clear conditions ! If == .FALSE., the CloudCoeff data will not be loaded; ! == .TRUE., the CloudCoeff data will be loaded. ! If not specified, default is .TRUE. (will be loaded) ! UNITS: N/A ! TYPE: LOGICAL ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN), OPTIONAL ! ! Load_AerosolCoeff: Set this logical argument for not loading the AerosolCoeff data ! to save memory space under the clear conditions ! If == .FALSE., the AerosolCoeff data will not be loaded; ! == .TRUE., the AerosolCoeff data will be loaded. ! If not specified, default is .TRUE. (will be loaded) ! UNITS: N/A ! TYPE: LOGICAL ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN), OPTIONAL ! ! Quiet: Set this logical argument to suppress INFORMATION ! messages being printed to stdout ! If == .FALSE., INFORMATION messages are OUTPUT [DEFAULT]. ! == .TRUE., INFORMATION messages are SUPPRESSED. ! If not specified, default is .FALSE. ! UNITS: N/A ! TYPE: LOGICAL ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN), OPTIONAL ! ! Process_ID: Set this argument to the MPI process ID that this ! function call is running under. This value is used ! solely for controlling INFORMATION message output. ! If MPI is not being used, ignore this argument. ! This argument is ignored if the Quiet argument is set. ! UNITS: N/A ! TYPE: INTEGER ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN), OPTIONAL ! ! Output_Process_ID: Set this argument to the MPI process ID in which ! all INFORMATION messages are to be output. If ! the passed Process_ID value agrees with this value ! the INFORMATION messages are output. ! This argument is ignored if the Quiet argument ! is set. ! UNITS: N/A ! TYPE: INTEGER ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN), OPTIONAL ! ! FUNCTION RESULT: ! Error_Status: The return value is an integer defining the error ! status. The error codes are defined in the ! Message_Handler module. ! If == SUCCESS the CRTM initialisation was successful ! == FAILURE an unrecoverable error occurred. ! UNITS: N/A ! TYPE: INTEGER ! DIMENSION: Scalar ! ! SIDE EFFECTS: ! All public data arrays accessed by this module and its dependencies ! are overwritten. ! ! RESTRICTIONS: ! If specified, the length of the combined file path and filename strings ! cannot exceed 2000 characters. ! !:sdoc-: !------------------------------------------------------------------------------ FUNCTION CRTM_Init( & Sensor_ID , & ! Input ChannelInfo , & ! Output CloudCoeff_File , & ! Optional input AerosolCoeff_File, & ! Optional input EmisCoeff_File , & ! Optional input File_Path , & ! Optional input Load_CloudCoeff , & ! Optional input Load_AerosolCoeff, & ! Optional input Quiet , & ! Optional input Process_ID , & ! Optional input Output_Process_ID) & ! Optional input RESULT( err_stat ) ! Arguments CHARACTER(*) , INTENT(IN) :: Sensor_ID(:) TYPE(CRTM_ChannelInfo_type), INTENT(OUT) :: ChannelInfo(:) CHARACTER(*), OPTIONAL, INTENT(IN) :: CloudCoeff_File CHARACTER(*), OPTIONAL, INTENT(IN) :: AerosolCoeff_File CHARACTER(*), OPTIONAL, INTENT(IN) :: EmisCoeff_File CHARACTER(*), OPTIONAL, INTENT(IN) :: File_Path LOGICAL , OPTIONAL, INTENT(IN) :: Load_CloudCoeff LOGICAL , OPTIONAL, INTENT(IN) :: Load_AerosolCoeff LOGICAL , OPTIONAL, INTENT(IN) :: Quiet INTEGER , OPTIONAL, INTENT(IN) :: Process_ID INTEGER , OPTIONAL, INTENT(IN) :: Output_Process_ID ! Function result INTEGER :: err_stat ! Local parameters CHARACTER(*), PARAMETER :: ROUTINE_NAME = 'CRTM_Init' ! Local variables CHARACTER(ML) :: msg, pid_msg CHARACTER(SL) :: Default_CloudCoeff_File CHARACTER(SL) :: Default_AerosolCoeff_File CHARACTER(SL) :: Default_EmisCoeff_File INTEGER :: l, n, n_Sensors LOGICAL :: Local_Load_CloudCoeff LOGICAL :: Local_Load_AerosolCoeff ! ****** ! TEMPORARY UNTIL LOAD ROUTINE INTERFACES HAVE BEEN MODIFIED INTEGER :: iQuiet iQuiet = 0 IF ( PRESENT(Quiet) ) THEN IF ( Quiet ) THEN iQuiet = 1 ! Set END IF END IF ! ****** ! Set up err_stat = SUCCESS ! ...Create a process ID message tag for error messages IF ( PRESENT(Process_Id) ) THEN WRITE( pid_msg,'("; Process ID: ",i0)' ) Process_ID ELSE pid_msg = '' END IF ! ...Check coefficient loading flags Local_Load_CloudCoeff = .TRUE. IF( PRESENT(Load_CloudCoeff) ) Local_Load_CloudCoeff = Load_CloudCoeff Local_Load_AerosolCoeff = .TRUE. IF( PRESENT(Load_AerosolCoeff) ) Local_Load_AerosolCoeff = Load_AerosolCoeff ! ...Check dimensionality n_Sensors = SIZE(Sensor_ID) IF ( SIZE(ChannelInfo) /= n_Sensors ) THEN err_stat = FAILURE msg = 'Inconsistent Sensor_ID and ChannelInfo dimensions' CALL Display_Message( ROUTINE_NAME,TRIM(msg)//TRIM(pid_msg),err_stat ) RETURN END IF ! Specify sensor-independent coefficient filenames ! ...Default filenames Default_CloudCoeff_File = 'CloudCoeff.bin' Default_AerosolCoeff_File = 'AerosolCoeff.bin' Default_EmisCoeff_File = 'EmisCoeff.bin' ! ...Were other filenames specified? IF ( PRESENT(CloudCoeff_File ) ) Default_CloudCoeff_File = TRIM(ADJUSTL(CloudCoeff_File)) IF ( PRESENT(AerosolCoeff_File) ) Default_AerosolCoeff_File = TRIM(ADJUSTL(AerosolCoeff_File)) IF ( PRESENT(EmisCoeff_File ) ) Default_EmisCoeff_File = TRIM(ADJUSTL(EmisCoeff_File)) ! ...Was a path specified? IF ( PRESENT(File_Path) ) THEN Default_CloudCoeff_File = TRIM(ADJUSTL(File_Path)) // TRIM(Default_CloudCoeff_File) Default_AerosolCoeff_File = TRIM(ADJUSTL(File_Path)) // TRIM(Default_AerosolCoeff_File) Default_EmisCoeff_File = TRIM(ADJUSTL(File_Path)) // TRIM(Default_EmisCoeff_File) END IF ! Load the spectral coefficients err_stat = CRTM_Load_SpcCoeff( & Sensor_ID = Sensor_ID , & File_Path = File_Path , & Quiet = iQuiet , & ! *** Use of iQuiet temporary Process_ID = Process_ID , & Output_Process_ID = Output_Process_ID ) IF ( err_stat /= SUCCESS ) THEN CALL Display_Message( ROUTINE_NAME,'Error loading SpcCoeff data'//TRIM(pid_msg),err_stat ) RETURN END IF ! Load the transmittance model coefficients err_stat = CRTM_Load_TauCoeff( & Sensor_ID = Sensor_ID , & File_Path = File_Path , & Quiet = iQuiet , & ! *** Use of iQuiet temporary Process_ID = Process_ID , & Output_Process_ID = Output_Process_ID ) IF ( err_stat /= SUCCESS ) THEN CALL Display_Message( ROUTINE_NAME,'Error loading TauCoeff data'//TRIM(pid_msg),err_stat ) RETURN END IF ! Load the cloud coefficients IF ( Local_Load_CloudCoeff ) THEN err_stat = CRTM_CloudCoeff_Load( & Default_CloudCoeff_File, & Quiet = Quiet , & Process_ID = Process_ID , & Output_Process_ID = Output_Process_ID ) IF ( err_stat /= SUCCESS ) THEN msg = 'Error loading CloudCoeff data from '//TRIM(Default_CloudCoeff_File) CALL Display_Message( ROUTINE_NAME,TRIM(msg)//TRIM(pid_msg),err_stat ) RETURN END IF END IF ! Load the aerosol coefficients IF ( Local_Load_AerosolCoeff ) THEN err_stat = CRTM_AerosolCoeff_Load( & Default_AerosolCoeff_File, & Quiet = Quiet , & Process_ID = Process_ID , & Output_Process_ID = Output_Process_ID ) IF ( err_stat /= SUCCESS ) THEN msg = 'Error loading AerosolCoeff data from '//TRIM(Default_AerosolCoeff_File) CALL Display_Message( ROUTINE_NAME,TRIM(msg)//TRIM(pid_msg),err_stat ) RETURN END IF END IF ! Load the emissivity model coefficients ! ...IR Water err_stat = CRTM_Load_EmisCoeff( & Default_EmisCoeff_File, & Quiet = iQuiet , & ! *** Use of iQuiet temporary Process_ID = Process_ID , & Output_Process_ID = Output_Process_ID ) IF ( err_stat /= SUCCESS ) THEN msg = 'Error loading IR Water EmisCoeff data from '//TRIM(Default_EmisCoeff_File) CALL Display_Message( ROUTINE_NAME,TRIM(msg)//TRIM(pid_msg),err_stat ) RETURN END IF ! Load the ChannelInfo structure ! **** THIS CODE ASSUMES USING ALL CHANNELS **** DO n = 1, n_Sensors ! ...Allocate the ChannelInfo structure CALL CRTM_ChannelInfo_Create( ChannelInfo(n), SC(n)%n_Channels ) IF ( .NOT. CRTM_ChannelInfo_Associated(ChannelInfo(n)) ) THEN msg = 'ChannelInfo allocation failed for '//TRIM(Sensor_Id(n))//' sensor' CALL Display_Message( ROUTINE_NAME,TRIM(msg)//TRIM(pid_msg),err_stat ) RETURN END IF ! ...Set the Sensor_Index component ChannelInfo(n)%Sensor_Index = n ! ...Fill the Channel_Index component ! **** THIS IS WHERE CHANNEL SELECTION COULD OCCUR **** ChannelInfo(n)%Channel_Index = (/(l, l=1,SC(n)%n_Channels)/) ! ...Fill the rest of the ChannelInfo structure ChannelInfo(n)%Sensor_ID = SC(n)%Sensor_Id ChannelInfo(n)%WMO_Satellite_ID = SC(n)%WMO_Satellite_ID ChannelInfo(n)%WMO_Sensor_ID = SC(n)%WMO_Sensor_ID ChannelInfo(n)%Sensor_Channel = SC(n)%Sensor_Channel END DO END FUNCTION CRTM_Init !------------------------------------------------------------------------------ !:sdoc+: ! ! NAME: ! CRTM_Destroy ! ! PURPOSE: ! Function to deallocate all the shared data arrays allocated and ! populated during the CRTM initialization. ! ! CALLING SEQUENCE: ! Error_Status = CRTM_Destroy( ChannelInfo , & ! Process_ID = Process_ID ) ! ! OUTPUTS: ! ChannelInfo: Reinitialized ChannelInfo structure. ! UNITS: N/A ! TYPE: CRTM_ChannelInfo_type ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN OUT) ! ! OPTIONAL INPUTS: ! Process_ID: Set this argument to the MPI process ID that this ! function call is running under. This value is used ! solely for controlling message output. If MPI is not ! being used, ignore this argument. ! UNITS: N/A ! TYPE: INTEGER ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(IN), OPTIONAL ! ! FUNCTION RESULT: ! Error_Status: The return value is an integer defining the error ! status. The error codes are defined in the ! Message_Handler module. ! If == SUCCESS the CRTM deallocations were successful ! == FAILURE an unrecoverable error occurred. ! UNITS: N/A ! TYPE: INTEGER ! DIMENSION: Scalar ! ! SIDE EFFECTS: ! All CRTM shared data arrays and structures are deallocated. ! ! COMMENTS: ! Note the INTENT on the output ChannelInfo argument is IN OUT rather than ! just OUT. This is necessary because the argument may be defined upon ! input. To prevent memory leaks, the IN OUT INTENT is a must. ! !:sdoc-: !------------------------------------------------------------------------------ FUNCTION CRTM_Destroy( & ChannelInfo, & ! Output Process_ID ) & ! Optional input RESULT( err_stat ) ! Arguments TYPE(CRTM_ChannelInfo_type), INTENT(IN OUT) :: ChannelInfo(:) INTEGER, OPTIONAL, INTENT(IN) :: Process_ID ! Function result INTEGER :: err_stat ! Local parameters CHARACTER(*), PARAMETER :: ROUTINE_NAME = 'CRTM_Destroy' ! Local variables CHARACTER(ML) :: msg, pid_msg INTEGER :: Destroy_Status ! Set up err_stat = SUCCESS ! ...Create a process ID message tag for error messages IF ( PRESENT(Process_Id) ) THEN WRITE( pid_msg,'("; Process ID: ",i0)' ) Process_ID ELSE pid_msg = '' END IF ! Destroy all the ChannelInfo structures CALL CRTM_ChannelInfo_Destroy( ChannelInfo ) IF ( ANY(CRTM_ChannelInfo_Associated(ChannelInfo)) ) THEN err_stat = FAILURE msg = 'Error deallocating ChannelInfo structure(s)' CALL Display_Message( ROUTINE_NAME,TRIM(msg)//TRIM(pid_msg),err_stat ) END IF ! Destroy the shared data structure Destroy_Status = CRTM_Destroy_EmisCoeff( Process_ID = Process_ID ) IF ( Destroy_Status /= SUCCESS ) THEN err_stat = Destroy_Status CALL Display_Message( ROUTINE_NAME, & 'Error deallocating shared EmisCoeff data structure'//TRIM(pid_msg), & err_stat ) END IF Destroy_Status = CRTM_AerosolCoeff_Destroy( Process_ID = Process_ID ) IF ( Destroy_Status /= SUCCESS ) THEN err_stat = Destroy_Status CALL Display_Message( ROUTINE_NAME, & 'Error deallocating shared AerosolCoeff data structure'//TRIM(pid_msg), & err_stat ) END IF Destroy_Status = CRTM_CloudCoeff_Destroy( Process_ID = Process_ID ) IF ( Destroy_Status /= SUCCESS ) THEN err_stat = Destroy_Status CALL Display_Message( ROUTINE_NAME, & 'Error deallocating shared CloudCoeff data structure'//TRIM(pid_msg), & err_stat ) END IF Destroy_Status = CRTM_Destroy_TauCoeff( Process_ID = Process_ID ) IF ( Destroy_Status /= SUCCESS ) THEN err_stat = Destroy_Status CALL Display_Message( ROUTINE_NAME, & 'Error deallocating shared TauCoeff data structure(s)'//TRIM(pid_msg), & err_stat ) END IF Destroy_Status = CRTM_Destroy_SpcCoeff( Process_ID = Process_ID ) IF ( Destroy_Status /= SUCCESS ) THEN err_stat = Destroy_Status CALL Display_Message( ROUTINE_NAME, & 'Error deallocating shared SpcCoeff data structure(s)'//TRIM(pid_msg), & err_stat ) END IF END FUNCTION CRTM_Destroy !-------------------------------------------------------------------------------- !:sdoc+: ! ! NAME: ! CRTM_LifeCycleVersion ! ! PURPOSE: ! Subroutine to return the module version information. ! ! CALLING SEQUENCE: ! CALL CRTM_LifeCycleVersion( Id ) ! ! OUTPUT ARGUMENTS: ! Id: Character string containing the version Id information ! for the module. ! UNITS: N/A ! TYPE: CHARACTER(*) ! DIMENSION: Scalar ! ATTRIBUTES: INTENT(OUT) ! !:sdoc-: !-------------------------------------------------------------------------------- SUBROUTINE CRTM_LifeCycleVersion( Id ) CHARACTER(*), INTENT(OUT) :: Id Id = MODULE_VERSION_ID END SUBROUTINE CRTM_LifeCycleVersion END MODULE CRTM_LifeCycle