diff --git a/src/MNH/modeln.f90 b/src/MNH/modeln.f90
index b5ab334898edb2435108ee39274f9f58f0bd6ee0..2ae06f47d2024e6d5473f08773e1180b9f7174ef 100644
--- a/src/MNH/modeln.f90
+++ b/src/MNH/modeln.f90
@@ -397,8 +397,7 @@ USE MODE_ONE_WAY_n
 USE MODE_WRITE_AIRCRAFT_BALLOON
 use mode_write_les_n,               only: Write_les_n
 use mode_write_lfifmn_fordiachro_n, only: WRITE_LFIFMN_FORDIACHRO_n
-USE MODE_WRITE_PROFILER_n,          ONLY: WRITE_PROFILER_n
-USE MODE_WRITE_STATION_n,           ONLY: WRITE_STATION_n
+USE MODE_WRITE_STATPROF_n,          ONLY: WRITE_STATPROF_n
 !
 USE MODI_ADDFLUCTUATIONS
 USE MODI_ADVECTION_METSV
@@ -2271,8 +2270,8 @@ IF (OEXIT) THEN
   IF ( .NOT. LIO_NO_WRITE ) THEN
     IF (LSERIES) CALL WRITE_SERIES_n(TDIAFILE)
     CALL WRITE_AIRCRAFT_BALLOON(TDIAFILE)
-    CALL WRITE_STATION_n(TDIAFILE)
-    CALL WRITE_PROFILER_n(TDIAFILE)
+    CALL WRITE_STATPROF_n( TDIAFILE, TSTATIONS )
+    CALL WRITE_STATPROF_n( TDIAFILE, TPROFILERS )
     call Write_les_n( tdiafile )
 #ifdef MNH_IOLFI
     CALL MENU_DIACHRO(TDIAFILE,'END')
diff --git a/src/MNH/write_profilern.f90 b/src/MNH/write_profilern.f90
index 5cd2e0c0424c36fbbf79596c30da231dc8e480e8..bf58e8166d649f37ca6da7e60bedd6b5a4475b8f 100644
--- a/src/MNH/write_profilern.f90
+++ b/src/MNH/write_profilern.f90
@@ -31,7 +31,7 @@ implicit none
 
 private
 
-public :: WRITE_PROFILER_n
+public :: PROFILER_DIACHRO_n
 
 CHARACTER(LEN=NCOMMENTLGTMAX), DIMENSION(:), ALLOCATABLE :: CCOMMENT ! comment string
 CHARACTER(LEN=NMNHNAMELGTMAX), DIMENSION(:), ALLOCATABLE :: CTITLE   ! title
@@ -40,121 +40,6 @@ CHARACTER(LEN=NUNITLGTMAX),    DIMENSION(:), ALLOCATABLE :: CUNIT    ! physical
 REAL, DIMENSION(:,:,:,:,:,:), ALLOCATABLE :: XWORK6   ! contains temporal serie
 
 contains
-!
-!#######################################
-SUBROUTINE WRITE_PROFILER_n( TPDIAFILE )
-!#######################################
-!
-!
-!****  *WRITE_PROFILER* - write the profilers records in the diachronic file
-!
-!*      0. DECLARATIONS
-!          ------------
-!
-USE MODD_IO,              ONLY: ISNPROC, ISP, TFILEDATA
-USE MODD_MPIF
-USE MODD_PRECISION,       ONLY: MNHINT_MPI
-USE MODD_PROFILER_n,      only: NUMBPROFILER_LOC, TPROFILERS, TPROFILERS_TIME
-USE MODD_TYPE_STATPROF,   ONLY: TPROFILERDATA
-!
-USE MODE_MSG
-!
-IMPLICIT NONE
-!
-!
-!*      0.1  declarations of arguments
-!
-TYPE(TFILEDATA),  INTENT(IN) :: TPDIAFILE ! diachronic file to write
-!
-!-------------------------------------------------------------------------------
-!
-!       0.2  declaration of local variables
-!
-INTEGER :: IERR
-INTEGER :: JP, JS
-INTEGER :: IDX
-INTEGER :: INUMPROF  ! Total number of profilers (for the current model)
-INTEGER :: ISTORE
-INTEGER, DIMENSION(:), ALLOCATABLE :: INPROFPRC    ! Array to store the number of profilers per process (for the current model)
-INTEGER, DIMENSION(:), ALLOCATABLE :: IPROFIDS     ! Intermediate array for MPI communication
-INTEGER, DIMENSION(:), ALLOCATABLE :: IPROFPRCRANK ! Array to store the ranks of the processes where the profilers are
-INTEGER, DIMENSION(:), ALLOCATABLE :: IDS          ! Array to store the profiler number to send
-INTEGER, DIMENSION(:), ALLOCATABLE :: IDISP        ! Array to store the displacements for MPI communications
-TYPE(TPROFILERDATA) :: TZPROFILER
-!
-!----------------------------------------------------------------------------
-!
-
-ALLOCATE( INPROFPRC(ISNPROC) )
-ALLOCATE( IDS(NUMBPROFILER_LOC) )
-
-!Gather number of profiler present on each process
-CALL MPI_ALLGATHER( NUMBPROFILER_LOC, 1, MNHINT_MPI, INPROFPRC, 1, MNHINT_MPI, TPDIAFILE%NMPICOMM, IERR )
-
-!Store the identification number of local profilers (these numbers are globals)
-DO JS = 1, NUMBPROFILER_LOC
-  IDS(JS) = TPROFILERS(JS)%NID
-END DO
-
-ALLOCATE( IDISP(ISNPROC) )
-IDISP(1) = 0
-DO JP = 2, ISNPROC
-  IDISP(JP) = IDISP(JP-1) + INPROFPRC(JP-1)
-END DO
-
-INUMPROF = SUM( INPROFPRC(:) )
-ALLOCATE( IPROFIDS(INUMPROF) )
-ALLOCATE( IPROFPRCRANK(INUMPROF) )
-
-!Gather the list of all the profilers of all processes
-CALL MPI_ALLGATHERV( IDS(:), NUMBPROFILER_LOC, MNHINT_MPI, IPROFIDS(:), INPROFPRC(:), &
-                     IDISP(:), MNHINT_MPI, TPDIAFILE%NMPICOMM, IERR )
-
-!Store the rank of each process corresponding to a given profiler
-IDX = 1
-IPROFPRCRANK(:) = -1
-DO JP = 1, ISNPROC
-  DO JS = 1, INPROFPRC(JP)
-    IPROFPRCRANK(IPROFIDS(IDX)) = JP
-    IDX = IDX + 1
-  END DO
-END DO
-
-ISTORE = SIZE( TPROFILERS_TIME%TPDATES )
-
-CALL TZPROFILER%DATA_ARRAYS_ALLOCATE( ISTORE )
-
-IDX = 1
-
-PROFILER: DO JS = 1, INUMPROF
-  IF ( IPROFPRCRANK(JS) == TPDIAFILE%NMASTER_RANK ) THEN
-    !No communication necessary, the profiler data is already on the writer process
-    IF ( ISP == TPDIAFILE%NMASTER_RANK ) THEN
-      TZPROFILER = TPROFILERS(IDX)
-      IDX = IDX + 1
-    END IF
-  ELSE
-    !The profiler data is not on the writer process
-    IF ( ISP == IPROFPRCRANK(JS) ) THEN
-      ! This process has the data and needs to send it to the writer process
-      CALL TPROFILERS(IDX)%SEND_DEALLOCATE( KTO = TPDIAFILE%NMASTER_RANK, OSEND_SIZE_TO_RECEIVER = .FALSE. )
-
-      IDX = IDX + 1
-    ELSE IF ( ISP == TPDIAFILE%NMASTER_RANK ) THEN
-      ! This process is the writer and will receive the profiler data from its owner
-      CALL TZPROFILER%RECV_ALLOCATE( KFROM = IPROFPRCRANK(JS), KSTORE_CUR = ISTORE, KSTORE_MAX = ISTORE )
-    END IF
-  END IF
-
-  CALL PROFILER_DIACHRO_n( TPDIAFILE, TZPROFILER )
-
-END DO PROFILER
-
-! Deallocate arrays (if still allocated)
-IF ( TZPROFILER%NSTORE_MAX >= 0 ) CALL TZPROFILER%DATA_ARRAYS_DEALLOCATE( )
-
-END SUBROUTINE WRITE_PROFILER_n
-
 
 ! ####################################################
 SUBROUTINE PROFILER_DIACHRO_n( TPDIAFILE, TPPROFILER )
diff --git a/src/MNH/write_stationn.f90 b/src/MNH/write_stationn.f90
index ecdc90dfdd56443a08ec98aa04da991a008fb00d..99c9bba86f4384684649515c1ff14701bc6e720a 100644
--- a/src/MNH/write_stationn.f90
+++ b/src/MNH/write_stationn.f90
@@ -24,7 +24,7 @@ implicit none
 
 private
 
-public :: WRITE_STATION_n
+public :: STATION_DIACHRO_n
 
 CHARACTER(LEN=NCOMMENTLGTMAX), DIMENSION(:), ALLOCATABLE :: CCOMMENT ! comment string
 CHARACTER(LEN=NMNHNAMELGTMAX), DIMENSION(:), ALLOCATABLE :: CTITLE   ! title
@@ -33,120 +33,6 @@ CHARACTER(LEN=NUNITLGTMAX),    DIMENSION(:), ALLOCATABLE :: CUNIT    ! physical
 REAL, DIMENSION(:,:,:,:,:,:), ALLOCATABLE :: XWORK6   ! contains temporal serie
 
 contains
-!
-! #####################################
-SUBROUTINE WRITE_STATION_n( TPDIAFILE )
-! #####################################
-!
-!
-!****  *WRITE_STATION* - write the stations records in the diachronic file
-!
-!*      0. DECLARATIONS
-!          ------------
-!
-USE MODD_IO,              ONLY: ISNPROC, ISP, TFILEDATA
-USE MODD_MPIF
-USE MODD_PRECISION,       ONLY: MNHINT_MPI
-USE MODD_STATION_n,       ONLY: NUMBSTAT_LOC, TSTATIONS, TSTATIONS_TIME
-USE MODD_TYPE_STATPROF,   ONLY: TSTATIONDATA
-!
-USE MODE_MSG
-!
-IMPLICIT NONE
-!
-!
-!*      0.1  declarations of arguments
-!
-TYPE(TFILEDATA),  INTENT(IN) :: TPDIAFILE ! diachronic file to write
-!
-!-------------------------------------------------------------------------------
-!
-!       0.2  declaration of local variables
-!
-INTEGER :: IERR
-INTEGER :: JP, JS
-INTEGER :: IDX
-INTEGER :: INUMSTAT  ! Total number of stations (for the current model)
-INTEGER :: ISTORE
-INTEGER, DIMENSION(:), ALLOCATABLE :: INSTATPRC    ! Array to store the number of stations per process (for the current model)
-INTEGER, DIMENSION(:), ALLOCATABLE :: ISTATIDS     ! Intermediate array for MPI communication
-INTEGER, DIMENSION(:), ALLOCATABLE :: ISTATPRCRANK ! Array to store the ranks of the processes where the stations are
-INTEGER, DIMENSION(:), ALLOCATABLE :: IDS          ! Array to store the station number to send
-INTEGER, DIMENSION(:), ALLOCATABLE :: IDISP        ! Array to store the displacements for MPI communications
-TYPE(TSTATIONDATA) :: TZSTATION
-!
-!----------------------------------------------------------------------------
-
-ALLOCATE( INSTATPRC(ISNPROC) )
-ALLOCATE( IDS(NUMBSTAT_LOC) )
-
-!Gather number of station present on each process
-CALL MPI_ALLGATHER( NUMBSTAT_LOC, 1, MNHINT_MPI, INSTATPRC, 1, MNHINT_MPI, TPDIAFILE%NMPICOMM, IERR )
-
-!Store the identification number of local stations (these numbers are globals)
-DO JS = 1, NUMBSTAT_LOC
-  IDS(JS) = TSTATIONS(JS)%NID
-END DO
-
-ALLOCATE( IDISP(ISNPROC) )
-IDISP(1) = 0
-DO JP = 2, ISNPROC
-  IDISP(JP) = IDISP(JP-1) + INSTATPRC(JP-1)
-END DO
-
-INUMSTAT = SUM( INSTATPRC(:) )
-ALLOCATE( ISTATIDS(INUMSTAT) )
-ALLOCATE( ISTATPRCRANK(INUMSTAT) )
-
-!Gather the list of all the stations of all processes
-CALL MPI_ALLGATHERV( IDS(:), NUMBSTAT_LOC, MNHINT_MPI, ISTATIDS(:), INSTATPRC(:), &
-                     IDISP(:), MNHINT_MPI, TPDIAFILE%NMPICOMM, IERR )
-
-!Store the rank of each process corresponding to a given station
-IDX = 1
-ISTATPRCRANK(:) = -1
-DO JP = 1, ISNPROC
-  DO JS = 1, INSTATPRC(JP)
-    ISTATPRCRANK(ISTATIDS(IDX)) = JP
-    IDX = IDX + 1
-  END DO
-END DO
-
-ISTORE = SIZE( TSTATIONS_TIME%TPDATES )
-
-CALL TZSTATION%DATA_ARRAYS_ALLOCATE( ISTORE )
-
-IDX = 1
-
-STATION: DO JS = 1, INUMSTAT
-  IF ( ISTATPRCRANK(JS) == TPDIAFILE%NMASTER_RANK ) THEN
-    !No communication necessary, the station data is already on the writer process
-    IF ( ISP == TPDIAFILE%NMASTER_RANK ) THEN
-      TZSTATION = TSTATIONS(IDX)
-      IDX = IDX + 1
-    END IF
-  ELSE
-    !The station data is not on the writer process
-    IF ( ISP == ISTATPRCRANK(JS) ) THEN
-      ! This process has the data and needs to send it to the writer process
-      CALL TSTATIONS(IDX)%SEND_DEALLOCATE( KTO = TPDIAFILE%NMASTER_RANK, OSEND_SIZE_TO_RECEIVER = .FALSE. )
-
-      IDX = IDX + 1
-    ELSE IF ( ISP == TPDIAFILE%NMASTER_RANK ) THEN
-      ! This process is the writer and will receive the station data from its owner
-      ! Remark: allocation is already done and will be skipped in RECV_ALLOCATE
-      CALL TZSTATION%RECV_ALLOCATE( KFROM = ISTATPRCRANK(JS), KSTORE_CUR = ISTORE, KSTORE_MAX = ISTORE )
-    END IF
-  END IF
-
-  CALL STATION_DIACHRO_n( TPDIAFILE, TZSTATION )
-
-END DO STATION
-
-! Deallocate arrays (if still allocated)
-IF ( TZSTATION%NSTORE_MAX >= 0 ) CALL TZSTATION%DATA_ARRAYS_DEALLOCATE( )
-
-END SUBROUTINE WRITE_STATION_n
 
 ! ##################################################
 SUBROUTINE STATION_DIACHRO_n( TPDIAFILE, TPSTATION )
diff --git a/src/MNH/write_statprofn.f90 b/src/MNH/write_statprofn.f90
new file mode 100644
index 0000000000000000000000000000000000000000..bf6ada28aef95922c210ab8967ebcea936c9a6a0
--- /dev/null
+++ b/src/MNH/write_statprofn.f90
@@ -0,0 +1,169 @@
+!MNH_LIC Copyright 2002-2023 CNRS, Meteo-France and Universite Paul Sabatier
+!MNH_LIC This is part of the Meso-NH software governed by the CeCILL-C licence
+!MNH_LIC version 1. See LICENSE, CeCILL-C_V1-en.txt and CeCILL-C_V1-fr.txt
+!MNH_LIC for details. version 1.
+!-----------------------------------------------------------------
+!  Module to initiate the writing for stations and profilers
+!  It was initially created to deduplicate code from the WRITE_STATION_n and WRITE_PROFILER_n subroutines.
+! Author:
+!  P. Wautelet 12/07/2023
+!
+!  Modifications
+! --------------------------------------------------------------------------
+!      #####################
+MODULE MODE_WRITE_STATPROF_n
+!      #####################
+
+  IMPLICIT NONE
+
+  PRIVATE
+
+  PUBLIC :: WRITE_STATPROF_n
+
+contains
+  !
+  ! ##################################################
+  SUBROUTINE WRITE_STATPROF_n( TPDIAFILE, TPSTATPROF )
+  ! ##################################################
+  !
+  !
+  !****  *WRITE_STATPROF_n* - write the stations or profilers records in the diachronic file
+  !
+  !*      0. DECLARATIONS
+  !          ------------
+  !
+  USE MODD_IO,              ONLY: ISNPROC, ISP, TFILEDATA
+  USE MODD_MPIF
+  USE MODD_PRECISION,       ONLY: MNHINT_MPI
+  USE MODD_PROFILER_n,      only: NUMBPROFILER_LOC, TPROFILERS, TPROFILERS_TIME
+  USE MODD_STATION_n,       ONLY: NUMBSTAT_LOC, TSTATIONS, TSTATIONS_TIME
+  USE MODD_TYPE_STATPROF,   ONLY: TSTATIONDATA, TSTATPROFDATA, TPROFILERDATA
+  !
+  USE MODE_MSG
+  USE MODE_WRITE_PROFILER_n, ONLY: PROFILER_DIACHRO_n
+  USE MODE_WRITE_STATION_n,  ONLY: STATION_DIACHRO_n
+  !
+  IMPLICIT NONE
+  !
+  !
+  !*      0.1  declarations of arguments
+  !
+  TYPE(TFILEDATA),                    INTENT(IN) :: TPDIAFILE  ! Diachronic file to write
+  CLASS(TSTATPROFDATA), DIMENSION(:), INTENT(IN) :: TPSTATPROF ! Stations/profilers to write
+  !
+  !-------------------------------------------------------------------------------
+  !
+  !       0.2  declaration of local variables
+  !
+  INTEGER :: IERR
+  INTEGER :: JP, JS
+  INTEGER :: IDX
+  INTEGER :: INUMSTATPROF      ! Total number of stations/profilers (for the current model)
+  INTEGER :: INUMSTATPROF_LOC  ! Number of local stations/profilers (for the current model)
+  INTEGER :: ISTORE
+  INTEGER, DIMENSION(:), ALLOCATABLE :: INSTATPROFPRC    ! Array to store the number of statprof per process (for the current model)
+  INTEGER, DIMENSION(:), ALLOCATABLE :: ISTATPROFIDS     ! Intermediate array for MPI communication
+  INTEGER, DIMENSION(:), ALLOCATABLE :: ISTATPROFPRCRANK ! Array to store the ranks of the processes where the statprof are
+  INTEGER, DIMENSION(:), ALLOCATABLE :: IDS              ! Array to store the statprof number to send
+  INTEGER, DIMENSION(:), ALLOCATABLE :: IDISP            ! Array to store the displacements for MPI communications
+  CLASS(TSTATPROFDATA), ALLOCATABLE :: TZSTATPROF
+  CLASS(TSTATPROFDATA), DIMENSION(:), POINTER :: TZSTATPROFLIST
+    !
+  !----------------------------------------------------------------------------
+
+  SELECT TYPE ( TPSTATPROF )
+    TYPE IS ( TPROFILERDATA )
+      INUMSTATPROF_LOC = NUMBPROFILER_LOC
+      ISTORE = SIZE( TPROFILERS_TIME%TPDATES )
+      ALLOCATE( TPROFILERDATA :: TZSTATPROF )
+      TZSTATPROFLIST => TPROFILERS
+
+    TYPE IS ( TSTATIONDATA )
+      INUMSTATPROF_LOC = NUMBSTAT_LOC
+      ISTORE = SIZE( TSTATIONS_TIME%TPDATES )
+      ALLOCATE( TSTATIONDATA :: TZSTATPROF )
+      TZSTATPROFLIST => TSTATIONS
+
+    CLASS DEFAULT
+      CALL PRINT_MSG( NVERB_ERROR, 'IO', 'WRITE_STATPROF_n', 'unknown type' )
+  END SELECT
+
+  ALLOCATE( INSTATPROFPRC(ISNPROC) )
+  ALLOCATE( IDS(INUMSTATPROF_LOC) )
+
+  !Gather number of stations/profilers present on each process
+  CALL MPI_ALLGATHER( INUMSTATPROF_LOC, 1, MNHINT_MPI, INSTATPROFPRC, 1, MNHINT_MPI, TPDIAFILE%NMPICOMM, IERR )
+
+  !Store the identification number of local stations (these numbers are globals)
+  DO JS = 1, INUMSTATPROF_LOC
+    IDS(JS) = TPSTATPROF(JS)%NID
+  END DO
+
+  ALLOCATE( IDISP(ISNPROC) )
+  IDISP(1) = 0
+  DO JP = 2, ISNPROC
+    IDISP(JP) = IDISP(JP-1) + INSTATPROFPRC(JP-1)
+  END DO
+
+  INUMSTATPROF = SUM( INSTATPROFPRC(:) )
+  ALLOCATE( ISTATPROFIDS(INUMSTATPROF) )
+  ALLOCATE( ISTATPROFPRCRANK(INUMSTATPROF) )
+
+  !Gather the list of all the stations of all processes
+  CALL MPI_ALLGATHERV( IDS(:), INUMSTATPROF_LOC, MNHINT_MPI, ISTATPROFIDS(:), INSTATPROFPRC(:), &
+                       IDISP(:), MNHINT_MPI, TPDIAFILE%NMPICOMM, IERR )
+
+  !Store the rank of each process corresponding to a given station/profiler
+  IDX = 1
+  ISTATPROFPRCRANK(:) = -1
+  DO JP = 1, ISNPROC
+    DO JS = 1, INSTATPROFPRC(JP)
+      ISTATPROFPRCRANK(ISTATPROFIDS(IDX)) = JP
+      IDX = IDX + 1
+    END DO
+  END DO
+
+  CALL TZSTATPROF%DATA_ARRAYS_ALLOCATE( ISTORE )
+
+  IDX = 1
+
+  STATPROF: DO JS = 1, INUMSTATPROF
+    IF ( ISTATPROFPRCRANK(JS) == TPDIAFILE%NMASTER_RANK ) THEN
+      !No communication necessary, the station data is already on the writer process
+      IF ( ISP == TPDIAFILE%NMASTER_RANK ) THEN
+        TZSTATPROF = TZSTATPROFLIST(IDX)
+        IDX = IDX + 1
+      END IF
+    ELSE
+      !The station data is not on the writer process
+      IF ( ISP == ISTATPROFPRCRANK(JS) ) THEN
+        ! This process has the data and needs to send it to the writer process
+        CALL TZSTATPROFLIST(IDX)%SEND( KTO = TPDIAFILE%NMASTER_RANK, OSEND_SIZE_TO_RECEIVER = .FALSE. )
+
+        IDX = IDX + 1
+      ELSE IF ( ISP == TPDIAFILE%NMASTER_RANK ) THEN
+        ! This process is the writer and will receive the station data from its owner
+        ! Remark: allocation is already done and will be skipped in RECV_ALLOCATE
+        CALL TZSTATPROF%RECV_ALLOCATE( KFROM = ISTATPROFPRCRANK(JS), KSTORE_CUR = ISTORE, KSTORE_MAX = ISTORE )
+      END IF
+    END IF
+
+    SELECT TYPE ( TZSTATPROF )
+      TYPE IS ( TPROFILERDATA )
+        CALL PROFILER_DIACHRO_n( TPDIAFILE, TZSTATPROF )
+
+      TYPE IS ( TSTATIONDATA )
+        CALL STATION_DIACHRO_n( TPDIAFILE, TZSTATPROF )
+
+      CLASS DEFAULT
+        CALL PRINT_MSG( NVERB_ERROR, 'IO', 'WRITE_STATPROF_n', 'unknown type' )
+    END SELECT
+
+  END DO STATPROF
+
+  ! Deallocate arrays (if still allocated)
+  IF ( TZSTATPROF%NSTORE_MAX >= 0 ) CALL TZSTATPROF%DATA_ARRAYS_DEALLOCATE( )
+
+  END SUBROUTINE WRITE_STATPROF_n
+
+END MODULE MODE_WRITE_STATPROF_N