It cannot be done during initialization because the CPP include syntax 
<*****.h> allows to use the header files from user's directories other than 
ROMS/Functionals.  Notice that in 
analytical.F, we have
Code: Select all
# ifdef SOLVE3D
#  if defined ANA_BIOLOGY && defined BIOLOGY
#   include <ana_biology.h>
#  endif
# endif
and any header file has something like:
Code: Select all
!
! Set analytical header file name used.
!
#ifdef DISTRIBUTE
      IF (Lanafile) THEN
#else
      IF (Lanafile.and.(tile.eq.0)) THEN
#endif
        ANANAME( 1)=__FILE__
      END IF
So the full path of 
ANANAME(:) for all the analytical header files used are only known during execution because of the 
__FILE__ syntax.
The header file for the ecosystem models is special.  Notice that in 
def_info.F we have:
Code: Select all
#ifdef BIOLOGY
!
!  Biology model header file used.
!
        IF (exit_flag.eq.NoError) THEN
          DO i=1,512
            bio_file(i:i)='-'
          END DO
          status=nf90_put_att(ncid, nf90_global, 'bio_file',            &
     &                        bio_file)
          IF (FoundError(status, nf90_noerr, __LINE__,                  &
     &                   __FILE__)) THEN
            IF (Master) WRITE (stdout,20) 'bio_file', TRIM(ncname)
            exit_flag=3
            ioerror=status
          END IF
        END IF
#endif
The global attribute 
bio_file is set when closing the output NetCDF file in 
netcdf_close:
Code: Select all
#ifdef BIOLOGY
!
!  Determine updating value of biology header files global attribute.
!  This is only possible in output files. An error occurs in input
!  files open for reading only. This allows to use ROMS input files
!  with the "bio_file" attribute.
!
        IF (.not.PRESENT(Lupdate)) THEN
          my_Lupdate=.TRUE.
        ELSE
          my_Lupdate=Lupdate
        END IF
!
!  Update global attribute with the biology header files used.
!
        IF (my_Lupdate) THEN
          is=1
          status=nf90_inquire_attribute(ncid, nf90_global, 'bio_file',  &
     &                                  len = AttLen)
          IF (status.eq.nf90_noerr) THEN
            DO i=1,512
              bio_file(i:i)=' '
            END DO
            DO i=1,4
              lstr=LEN_TRIM(BIONAME(i))
              IF (lstr.gt.0) THEN
                ie=is+lstr-1
                bio_file(is:ie)=TRIM(BIONAME(i))
                is=ie+1
                bio_file(is:is)=','
                is=is+2
              END IF
            END DO
            lstr=LEN_TRIM(bio_file)-1
            IF (lstr.gt.0) THEN
              status=nf90_put_att(ncid, nf90_global, 'bio_file',        &
     &                            bio_file(1:lstr))
              IF (FoundError(status, nf90_noerr, __LINE__,              &
     &                       __FILE__ //                                &
     &                       ", netcdf_close")) THEN
                WRITE (stdout,10) 'bio_file', TRIM(my_ncname),          &
     &                            TRIM(SourceFile)
                exit_flag=3
                ioerror=status
              END IF
            END IF
          END IF
        END IF
#endif
So to report all the header files together, I decided to write its usage at the end when there are visible instead of the middle of time-stepping.  So when you see weird things like that in ROMS, there is also a reason for it  

   I think that I mentioned this before in the documentation.