!--
! *** Caution!! ***
!
! This file is generated from "historycreate.rb2f90" by Ruby 2.3.3.
! Please do not edit this file directly.
!
! [JAPANESE]
!
! ※※※ 注意!!! ※※※
!
! このファイルは "historycreate.rb2f90" から Ruby 2.3.3
! によって自動生成されたファイルです.
! このファイルを直接編集しませんようお願い致します.
!
!
!++
!
!= gtool4 データ出力用初期設定
!= Initialzation of gtool4 data putput
!
! Authors::   Yasuhiro MORIKAWA, Eizi TOYODA
! Version::   $Id: historycreate.rb2f90,v 1.4 2009-11-03 05:22:46 morikawa Exp $
! Tag Name::  $Name:  $
! Copyright:: Copyright (C) GFD Dennou Club, 2000-2009. All rights reserved.
! License::   See COPYRIGHT[link:../../../COPYRIGHT]
!

  subroutine HistoryCreate1( &
    & file, title, source, institution, &
    & dims, dimsizes, longnames, units, origin, interval, &
    & xtypes, history, origind, intervald, conventions, gt_version, overwrite, quiet, &
    & flag_mpi_gather, flag_mpi_split, err )
    !
    !== gtool4 データ出力用初期設定
    !
    ! このサブルーチンは、gtool4 データ出力の初期設定を行います。
    ! HistoryAddVariable、 HistoryCopyVariable、 HistoryPut、
    ! HistoryAddAttr、 HistoryClose、 HistorySetTime
    ! を用いるためには、HistoryCreate による初期設定が必要です。
    !
    ! なお、プログラム内で HistoryCreate を呼び出した場合、
    ! プログラムを終了する前に必ず、 HistoryClose を呼び出して
    ! 終了処理を行なって下さい。
    !
    ! *HistoryCreate* というサブルーチン名は 2 つの別々の
    ! サブルーチンの総称名です。上記のサブルーチンも参照ください。
    !
    !
    ! Two specific subroutines shares common part:
    !
    ! Both two ones initializes a dataset *file*.
    ! The result of type GT_HISTORY will be returned by *history*
    ! or managed internally if omitted.
    ! Mandatory global attributes are defined by arguments
    ! *title*, *source*, and *institution*;
    ! they are all declared as ((character(len = *))).
    ! Spatial axis definitions have two different forms:
    ! a primitive one uses several arrays of various types:
    ! *dims*, *dimsizes*, *longnames*, *units*, and *xtypes*.
    ! Another sophisticated one has only array of type GT_HISTORY_AXIS,
    ! *axes*.
    ! Temporal definition is done without *origin*, *interval*.
    !
    use gtool_history_types, only: GT_HISTORY, GT_HISTORY_AXIS, GT_HISTORY_VARINFO, GT_HISTORY_ATTR
    use gtool_history_internal, only: default, gtool4_netCDF_Conventions, gtool4_netCDF_version
    use gtool_history_generic, only: HistoryAxisCreate
    use gtdata_generic,only: Create, put_attr, Get_Attr
    use dc_trace, only: BeginSub, EndSub, DbgMessage
    use dc_error,   only: StoreError, DC_NOERR, GT_EARGSIZEMISMATCH, DC_EALREADYINIT
    use dc_string, only: JoinChar, toChar, StoA, CPrintf, LChar
    use dc_url, only: UrlMerge
    use dc_present, only: present_and_not_empty, present_and_false, present_and_true
    use dc_types,   only: STRING, TOKEN, DP
    use dc_message, only: MessageNotify
    use dc_calendar, only: DC_CAL, DC_CAL_DATE, &
      & DCCalCreate, DCCalDateCurrent, DCCalDateInquire
    use dc_date_types, only: DC_DATETIME, DC_DIFFTIME, UNIT_SYMBOL_ERR, UNIT_SYMBOL_SEC
    use dc_date,  only: DCDateTimeCreate, toChar, DCDiffTimeCreate, &
      & EvalByUnit, ParseTimeUnits
    use sysdep,     only: SysdepEnvGet
#ifdef LIB_MPI
    use mpi
#endif
    implicit none
    character(*), intent(in):: file
                              ! 出力するファイルの名前. 
                              ! Name of output file
    character(*), intent(in):: title
                              ! データ全体の表題. 
                              ! Title of entire data
    character(*), intent(in):: source
                              ! データを作成する際の手段. 
                              ! Source of data file
    character(*), intent(in):: institution
                              ! ファイルを最終的に変更した組織/個人. 
                              ! Institution or person that changes files for the last time
    character(*), intent(in):: dims(:)
                              ! 次元の名前. 
                              ! 
                              ! 配列の大きさに制限はありません.
                              ! 個々の次元の文字数は dc_types#TOKEN まで.
                              ! 配列内の文字数は
                              ! 全て同じでなければなりません.
                              ! 足りない文字分は空白で
                              ! 補ってください.
                              ! 
                              ! Names of dimensions.
                              ! 
                              ! Length of array is unlimited. 
                              ! Limits of numbers of characters of each 
                              ! dimensions are "dc_types#TOKEN". 
                              ! Numbers of characters in this array
                              ! must be same. 
                              ! Make up a deficit with blanks. 
                              ! 
    integer, intent(in):: dimsizes (:)
                              ! dims で指定したそれぞれの次元大きさ. 
                              ! 
                              ! 配列の大きさは dims の大きさと等しい
                              ! 必要があります.  '0' (数字のゼロ) を指定
                              ! するとその次元は 無制限次元 (unlimited
                              ! dimension) となります. (gtool_history 
                              ! では時間の次元に対して無制限次元を
                              ! 用いることを想定しています). ただし, 
                              ! 1 つの NetCDF ファイル (バージョン 3) 
                              ! は最大で 1 つの無制限次元しか持てないので, 
                              ! 2 ヶ所以上に '0' を指定しないでください. 
                              ! その場合, 正しく gtool4 データが出力されません.
                              ! 
                              ! Lengths of dimensions specified with "dims". 
                              ! 
                              ! Length of this array must be same as 
                              ! length of "dim".  If '0' (zero) is 
                              ! specified, the dimension is treated as 
                              ! unlimited dimension.  
                              ! (In "gtool_history", unlimited dimension is 
                              ! expected to be used as time). 
                              ! Note that one NetCDF file (version 3) 
                              ! can not have two or more unlimited 
                              ! dimensions, so that do not specify '0' 
                              ! to two or more places. In that case, 
                              ! gtoo4 data is not output currently 
                              ! 
    character(*), intent(in):: longnames (:)
                              ! dims で指定したそれぞれの次元の名前. 
                              !
                              ! 配列の大きさは dims の大きさ
                              ! と等しい必要があります. 文字数
                              ! は dc_types#STRING まで.
                              ! 配列内の文字数は
                              ! 全て同じでなければなりません.
                              ! 足りない文字分は空白で補います.
                              ! 
                              ! Names of dimensions specified with "dims". 
                              !
                              ! Length of this array must be same as 
                              ! length of "dim".  
                              ! Limits of numbers of characters are 
                              ! "dc_types#STRING". 
                              ! Numbers of characters in this array
                              ! must be same. 
                              ! Make up a deficit with blanks. 
                              ! 
    character(*), intent(in):: units(:)
                              ! dims で指定したそれぞれの次元の単位. 
                              !
                              ! 配列の大きさは dims の大きさ
                              ! と等しい必要があります. 文字数
                              ! は dc_types#STRING まで.
                              ! 配列内の文字数は
                              ! 全て同じでなければなりません.
                              ! 足りない文字分は空白で補います.
                              ! 
                              ! Units of dimensions specified with "dims". 
                              !
                              ! Length of this array must be same as 
                              ! length of "dim".  
                              ! Limits of numbers of characters are 
                              ! "dc_types#STRING". 
                              ! Numbers of characters in this array
                              ! must be same. 
                              ! Make up a deficit with blanks. 
                              ! 
    real, intent(in), optional:: origin
                              ! 時間の原点. 
                              !
                              ! これは HistoryPut により変数を最初に
                              ! 出力するときの時間となります.
                              ! 
                              ! 省略した場合, 時間の原点には
                              ! 自動的に 0.0 が設定されます.
                              ! 
                              ! Origin of time. 
                              !
                              ! This time is used as time 
                              ! when first output is done by "HistoryPut". 
                              ! 
                              ! If this argument is omitted, 
                              ! 0.0 is specified automatically. 
                              ! 
    real, intent(in), optional:: interval
                              ! 出力時間間隔. 
                              !
                              ! 同じ変数に対して HistoryPut が複数回
                              ! 呼ばれた時に, 自動的に時間変数がこの値
                              ! だけ増やされて出力されます. なお, 
                              ! 各々の出力ファイルにつき HistorySetTime
                              ! を一度でも用いた場合, この値は無効に
                              ! なるので注意してください.
                              ! 
                              ! 省略した場合, 自動的に 1.0 が設定されます.
                              ! 
                              ! Interval of output time. 
                              !
                              ! When "HistoryPut" is called two or
                              ! more times for the same variable, time
                              ! is increased as this value and 
                              ! output automatically.
                              ! Note that this value becomes
                              ! invalid when "HistorySetTime" is 
                              ! used for each output file even once.
                              ! 
                              ! If this argument is omitted, 
                              ! 1.0 is specified automatically. 
                              ! 
    character(*), intent(in),  optional:: xtypes(:)
                              ! dims で指定したそれぞれの
                              ! 次元のデータ型. 
                              !
                              ! デフォルトは float (単精度実数型)
                              ! です. 有効なのは,
                              ! double (倍精度実数型), 
                              ! int (整数型) です. 指定しない
                              ! 場合や, 無効な型を指定した場合には,
                              ! float となります. なお, 配列の大きさ
                              ! は *dims* の大きさと等しい必要が
                              ! あります. 配列内の文字数は全て
                              ! 同じでなければなりません.
                              ! 足りない文字分は空白で補います.
                              !
                              ! Data types of dimensions specified 
                              ! with "dims". 
                              !
                              ! Default value is "float" (single precision). 
                              ! Other valid values are 
                              ! "double" (double precision), 
                              ! "int" (integer). 
                              ! If no value or invalid value is specified, 
                              ! "float" is applied. 
                              ! Length of this array must be same as 
                              ! length of "dim".  
                              ! Numbers of characters in this array
                              ! must be same. 
                              ! Make up a deficit with blanks. 
                              ! 
    type(GT_HISTORY), intent(out), optional, target:: history
                              ! 出力ファイルの設定に関する情報を
                              ! 格納した構造体. 
                              !
                              ! 1 つのプログラムで複数のファイル
                              ! に gtool データを出力する
                              ! 場合に利用します.
                              ! (単独のファイルに書き出す場合は
                              ! 指定する必要はありません)
                              ! 
                              ! Derived type that 
                              ! stores information about output files. 
                              !
                              ! If multiple gtool4 data files are 
                              ! output from one program, use this 
                              ! argument. 
                              ! (If onlye one file is output, 
                              ! this argument is not needed). 
                              ! 
    real(DP), intent(in), optional:: origind
                              ! 時間の原点. (倍精度実数) 
                              !
                              ! *time* と同様です. 
                              ! 
                              ! Origin of time. (Double precision)
                              !
                              ! This is same as *time*. 
                              ! 
    real(DP), intent(in), optional:: intervald
                              ! 出力時間間隔. (倍精度実数) 
                              ! 
                              ! *interval* と同様です. 
                              ! 
                              ! Interval of output time. (Double precision)
                              !
                              ! This is same as *interval*. 
                              ! 
    character(*), intent(in), optional:: conventions
                              ! 出力するファイルの netCDF
                              ! 規約
                              !
                              ! 省略した場合,
                              ! もしくは空文字を与えた場合,
                              ! 出力する netCDF 規約の
                              ! Conventions 属性に値
                              ! gtool_history_internal#gtool4_netCDF_Conventions
                              ! が自動的に与えられます.
                              ! 
                              ! NetCDF conventions of output file. 
                              !
                              ! If this argument is omitted or, 
                              ! blanks are given,
                              ! gtool_history_internal#gtool4_netCDF_Conventions is given to 
                              ! attribute "Conventions" of an output file
                              ! automatically. 
                              ! 
    character(*), intent(in), optional:: gt_version
                              ! gtool4 netCDF 規約のバージョン
                              !
                              ! 省略した場合, gt_version 属性に
                              ! 規約の最新版のバージョンナンバー
                              ! gtool4_netCDF_version
                              ! が与えられます.
                              ! (ただし, 引数 conventions に
                              ! gtool_history_internal#gtool4_netCDF_Conventions
                              ! 以外が与えられる場合は
                              ! gt_version 属性を作成しません).
                              ! 
                              ! Version of gtool4 netCDF Conventions. 
                              !
                              ! If this argument is omitted, 
                              ! latest version number of gtool4 netCDF 
                              ! Conventions is given to attribute 
                              ! "gt_version" of an output file 
                              ! (However, gtool_history_internal#gtool4_netCDF_Conventions is 
                              ! not given to an argument "conventions", 
                              ! attribute "gt_version" is not created).
                              ! 
    logical, intent(in), optional:: overwrite
                              ! 上書き可否
                              !
                              ! この引数に .false. を渡すと,
                              ! 既存のファイルを上書きしません.
                              ! デフォルトは上書きします.
                              ! 
                              ! Whether or not to overwrite. 
                              !
                              ! If .false. is specified to this 
                              ! argument, an existing file is not
                              ! overwritten. 
                              ! By default, existing file is overwritten. 
                              ! 
    logical, intent(in), optional:: quiet
                              ! .true. を与えた場合, 
                              ! メッセージ出力が抑制されます. 
                              ! デフォルトは .false. です. 
                              !
                              ! If ".true." is given, 
                              ! messages are suppressed. 
                              ! Default value is ".false.".
                              ! 
    logical, intent(in), optional:: flag_mpi_gather
                              ! MPI 使用時に, 各ノードで HistoryPut
                              ! に与えたデータを一つのファイルに統合して出力
                              ! する場合には .true. を与えてください. 
                              ! デフォルトは .false. です. 
                              ! 
                              ! .true. を与えた場合, HistoryPutAxisMPI
                              ! に全体の軸データを与えてください. 
                              !
                              ! When MPI is used, if ".true." is given, 
                              ! data given to "HistoryPut" on each node
                              ! is integrated and output to one file. 
                              ! Default value is ".false.".
                              ! 
                              ! If .true. is given, give data of axes in
                              ! whole area to "HistoryPutAxisMPI"
                              ! 
    logical, intent(in), optional:: flag_mpi_split
                              ! MPI 使用時にこの引数に .true. を与えると, 
                              ! 各ノードごとに
                              ! *file* 引数に "_rankXXXXXX" 
                              ! (X は [0-9] の数値で, ノード番号を指す) 
                              ! を付加したファイルを出力します. 
                              ! 例えば, *file* に "output.nc" を与えた場合. 
                              ! ノード 0 では "output_rank000000.nc", 
                              ! ノード 12 では "output_rank000012.nc"
                              ! を出力します. 
                              ! デフォルトは .false. です. 
                              !
                              ! When MPI is used, if ".true." is given, 
                              ! files that have names with suffixes
                              ! "_rankXXXXXX" 
                              ! (X is [0-9] that indicates node number) 
                              ! are output on each node. 
                              ! For example, "output.nc" is given to *file*, 
                              ! "output_rank000000.nc", "output_rank000012.nc"
                              ! are output on node 0 and node 12. 
                              ! Default value is ".false.".
                              ! 
    logical, intent(out), optional:: err
                              ! 例外処理用フラグ.
                              ! デフォルトでは, この手続き内でエラーが
                              ! 生じた場合, プログラムは強制終了します.
                              ! 引数 *err* が与えられる場合,
                              ! プログラムは強制終了せず, 代わりに
                              ! *err* に .true. が代入されます.
                              !
                              ! Exception handling flag. 
                              ! By default, when error occur in 
                              ! this procedure, the program aborts. 
                              ! If this *err* argument is given, 
                              ! .true. is substituted to *err* and 
                              ! the program does not abort. 
    integer:: numdims, i, stat, blank_index
    type(GT_HISTORY), pointer:: hst =>null()
    character(TOKEN):: my_xtype, origin_str!, interval_str
    character(STRING):: file_work, url, x_inst, x_conv, x_gtver, nc_history
    character(STRING):: cause_c
    logical:: gtver_add, overwrite_required
    character(TOKEN):: username
    type(DC_CAL):: cal_standard
    type(DC_CAL_DATE):: now_date
    character(TOKEN):: now_date_str
#ifdef LIB_MPI
    integer:: err_mpi, index_nc_mpi
    character(STRING):: file_mpi
    character(TOKEN):: myrank_str_mpi, nc_suffix_mpi
#endif
    character(*), parameter:: subname = "HistoryCreate1"
    character(*), parameter:: version = &
      & '$Name:  $' // &
      & '$Id: historycreate.rb2f90,v 1.4 2009-11-03 05:22:46 morikawa Exp $'
  continue
    call BeginSub(subname, 'file=%c ndims=%d',  &
      & c1=trim(file), i=(/size(dims)/), &
      & version=version)
    stat = DC_NOERR
    cause_c = ""

    call DbgMessage( &
      & 'dims(:)=%a, dimsizes(:)=%a, longnames(:)=%a, units(:)=%a', &
      & ca=StoA(JoinChar(dims), toChar(dimsizes), &
      &         JoinChar(longnames), JoinChar(units)))

    if (present(history)) then
      hst => history
    else
      hst => default
    endif

    ! 初期設定のチェック
    ! Check initialization
    !
    if ( hst % initialized ) then
      stat = DC_EALREADYINIT
      cause_c = 'GT_HISTORY'
      goto 999
    end if

    ! dims, dimsizes, longnames, units の整合性チェック
    ! Check consistency about "dims", "dimsizes", "longnames", "units"
    !
    numdims = size(dims)

    if ( size(dimsizes)  /= numdims ) then
      cause_c = 'dimsizes, dims'
    elseif ( size(longnames) /= numdims ) then
      cause_c = 'longnames, dims'
    elseif ( size(units) /= numdims ) then
      cause_c = 'units, dims'
    endif
    if ( trim(cause_c) /= "" ) then
      stat = GT_EARGSIZEMISMATCH
      goto 999
    end if

    ! 次元変数表作成. 
    ! Create table of dimensional variables
    !
    allocate(hst % dimvars(numdims))
    allocate(hst % dim_value_written(numdims))
    hst % dim_value_written(:) = .false.
    hst % unlimited_index = 0

    ! ユーザ名の取得
    ! Get user name
    !
    call SysdepEnvGet('USER', username)
    if (trim(username) == '') username = 'unknown'

    ! 現在時刻の取得
    ! Get current time
    !
    call DCCalDateCurrent( now_date )
    call DCCalCreate( 'gregorian', cal_standard )
    call DCCalDateInquire( now_date_str, date = now_date, cal = cal_standard )
!    call DCDateTimeCreate(now_time)
    nc_history = trim(now_date_str) // ' ' // &
      &       trim(username) // &
      &       '> gtool_history: HistoryCreate' // &
      &       achar(10)

    ! MPI に関連する情報の初期設定
    ! Initialize information about MPI
    !
#ifdef LIB_MPI
    hst % mpi_gather = present_and_true( flag_mpi_gather )
    hst % mpi_split  = present_and_true( flag_mpi_split )
    allocate( hst % mpi_fileinfo )
    allocate( hst % mpi_fileinfo % axes(numdims) )
    allocate( hst % mpi_dimdata_all(numdims) )
    allocate( hst % mpi_dimdata_each(numdims) )
    if ( hst % unlimited_index /= 0 ) then
      hst % mpi_dimdata_all( hst % unlimited_index ) % length = 0
      hst % mpi_dimdata_each( hst % unlimited_index ) % length = 0
    end if
#else
    hst % mpi_gather = .false.
    hst % mpi_split  = .false.
#endif

    ! MPI 使用時のファイル名の扱い
    ! Treat file names when MPI is used
    !
#ifndef LIB_MPI
    file_work = file
#else
    file_work = file
    if ( hst % mpi_gather .or. hst % mpi_split ) then
      call MPI_Comm_Rank(MPI_COMM_WORLD, hst % mpi_myrank, err_mpi)
      call MPI_Comm_Size(MPI_COMM_WORLD, hst % mpi_nprocs, err_mpi)
    end if
    if ( hst % mpi_split ) then
      file_mpi = file
      myrank_str_mpi = CPrintf( '_rank%06d', i = (/ hst % mpi_myrank /) )
      index_nc_mpi = index( LChar(file_mpi), '.nc' )
      if ( index_nc_mpi > 1 ) then
        nc_suffix_mpi = file_mpi(index_nc_mpi:)
        file_mpi = file_mpi(:index_nc_mpi-1) // trim( myrank_str_mpi ) // trim( nc_suffix_mpi )
      elseif ( index_nc_mpi > 0 ) then
        file_mpi = trim( myrank_str_mpi ) // trim( file_mpi )
      else
        file_mpi = trim( file_mpi ) // trim( myrank_str_mpi )
      end if
      file_work = file_mpi
    end if
#endif

    ! 変数 URL (出力ファイル) の作成
    ! Create variable URL (output file)
    !
    do, i = 1, numdims
      my_xtype = ""
      if ( present(xtypes) ) then
        if ( size(xtypes) >= i ) then
          my_xtype = xtypes(i)
        end if
      end if

#ifndef LIB_MPI
      url = UrlMerge(file=file, var=dims(i))
#else
      if ( hst % mpi_split ) then
        url = UrlMerge(file=file_mpi, var=dims(i))
      else
        url = UrlMerge(file=file, var=dims(i))
      end if
#endif
      overwrite_required = .true.
      if (present_and_false(overwrite)) overwrite_required = .false.

#ifdef LIB_MPI
      if ( .not. hst % mpi_gather ) then
#endif
      call Create( &
        & hst % dimvars(i), trim(url), &
        & dimsizes(i), xtype=trim(my_xtype), &
        & overwrite=overwrite_required)
      ! conventions が存在しない場合はデフォルトの値を
      ! 属性 Conventions に付加。
      if ( present_and_not_empty(conventions) ) then
        x_conv = conventions
      else
        x_conv  = gtool4_netCDF_Conventions
      endif
      ! 1) gt_version がある場合、それを gt_version 属性に渡す。
      ! 2) gt_version が無い場合、conventions も無いか、または
      !    gtool4 netCDF 規約が入っていれば最新版を gt_version
      !    に与える。そうでない場合は gt_version 属性を与えない。

      if (present_and_not_empty(gt_version)) then
        x_gtver = gt_version
        gtver_add = .TRUE.
      else
        if ( present_and_not_empty(conventions) .and. &
          &  .not. x_conv == gtool4_netCDF_Conventions ) then
          gtver_add = .FALSE.
        else
          x_gtver = gtool4_netCDF_version
          gtver_add = .TRUE.
        endif
      endif
      if (trim(institution) /= "") then
        x_inst = institution
      else
        x_inst = "a gtool_history (by GFD Dennou Club) user"
      endif
      call Put_Attr(hst % dimvars(i), '+Conventions', trim(x_conv))
      if (gtver_add) then
        call Put_Attr(hst % dimvars(i), '+gt_version', trim(x_gtver))
      endif
      ! title, source, institution, history, long_name, units 属性の付加
      call Put_Attr(hst % dimvars(i), '+title', title)
      call Put_Attr(hst % dimvars(i), '+source', source)
      call Put_Attr(hst % dimvars(i), '+institution', trim(x_inst))
      call Put_Attr(hst % dimvars(i), '+history', trim(nc_history))
      call Put_Attr(hst % dimvars(i), 'long_name', trim(longnames(i)))
      call Put_Attr(hst % dimvars(i), 'units', trim(units(i)))

#ifdef LIB_MPI
      else

        my_xtype = ""
        if ( present(xtypes) ) then
          if ( size(xtypes) >= i ) then
            my_xtype = xtypes(i)
          end if
        end if

        call HistoryAxisCreate( hst % mpi_fileinfo % axes(i), &
          & dims(i), dimsizes(i), longnames(i), units(i), my_xtype )

        hst % mpi_fileinfo % file   = file
        hst % mpi_fileinfo % title  = title
        hst % mpi_fileinfo % source = source

        hst % mpi_fileinfo % overwrite = .true.
        if (present_and_false(overwrite)) &
          & hst % mpi_fileinfo % overwrite = .false.

        if ( present_and_not_empty(conventions) ) then
          hst % mpi_fileinfo % conventions = conventions
        else
          hst % mpi_fileinfo % conventions = gtool4_netCDF_Conventions
        endif

        if (present_and_not_empty(gt_version)) then
          hst % mpi_fileinfo % gt_version = gt_version
          hst % mpi_fileinfo % gtver_add = .TRUE.
        else
          if ( present_and_not_empty(conventions) .and. &
            & .not. hst % mpi_fileinfo % conventions == gtool4_netCDF_Conventions ) then
            hst % mpi_fileinfo % gtver_add = .FALSE.
          else
            hst % mpi_fileinfo % gt_version = gtool4_netCDF_version
            hst % mpi_fileinfo % gtver_add = .TRUE.
          endif
        endif
      
        if (trim(institution) /= "") then
          hst % mpi_fileinfo % institution = institution
        else
          hst % mpi_fileinfo % institution = "a gtool_history (by GFD Dennou Club) user"
        endif

        hst % mpi_fileinfo % quiet = .false.
        hst % mpi_fileinfo % quiet = present_and_true(quiet)

        hst % mpi_fileinfo % nc_history = nc_history

      end if
#endif

      if (dimsizes(i) == 0) then
        hst % unlimited_index = i
        hst % unlimited_units = units(i)
      end if
    enddo

    ! 従属変数表の初期化
    ! Initialize table of dependent variables
    !
    nullify(hst % vars, hst % growable_indices, hst % count)

    ! 時刻の単位
    !
    if ( hst % unlimited_index == 0 ) then
      hst % unlimited_units_symbol = UNIT_SYMBOL_SEC
    else
      blank_index = index( trim( adjustl(hst % unlimited_units) ), ' ' )
      if ( blank_index > 1  ) then
        hst % unlimited_units = hst % unlimited_units(1:blank_index-1)
      end if
      hst % unlimited_units_symbol = ParseTimeUnits( hst % unlimited_units )

      if ( hst % unlimited_units_symbol == UNIT_SYMBOL_ERR ) then
        call MessageNotify('W', subname, &
          & 'units of time (%c) can not be recognized as units of time. ' // &
          & 'This units is treated as (%c)', &
          & c1 = trim(hst % unlimited_units), c2 = 'sec')
        hst % unlimited_units_symbol = UNIT_SYMBOL_SEC
      end if
    end if

    ! 時間カウンタ
    !
    if ( present(interval) ) then
      hst % interval = interval
    elseif ( present(intervald) ) then
      hst % interval = intervald
    else
      hst % interval = 1.0
    end if

    if ( present (origin) ) then
      hst % origin = origin
      hst % origin_setting = .true.
    elseif( present(origind) ) then
      hst % origin = origind
      hst % origin_setting = .true.
    else
      hst % origin = 0.0
      hst % origin_setting = .false.
    end if
    origin_str = trim( toChar( hst % origin ) ) // &
      &          ' [' // trim( hst % unlimited_units ) // ']'

    hst % newest = hst % origin
    hst % oldest = hst % origin

    ! 時間平均値出力に関するデフォルト設定 
    ! Default settings for time-averaged value output
    !
    hst % time_bnds = hst % origin
    hst % time_bnds_output_count = 0

    ! メッセージ出力
    ! Output messages
    !
#ifdef LIB_MPI
    if ( .not. hst % mpi_gather ) then
#endif

    if ( .not. present_and_true(quiet) ) then
      call MessageNotify('M', subname, &
        & '"%c" is created (origin=%c)', &
        & c1 = trim( file_work ), &
        & c2 = trim( origin_str ), rank_mpi = -1 )
    end if

#ifdef LIB_MPI
    end if
#endif

    ! 終了処理, 例外処理
    ! Termination and Exception handling
    !
    hst % initialized = .true.
999 continue
    call StoreError(stat, subname, err, cause_c=cause_c)
    call EndSub(subname, 'stat=%d', i = (/stat/) )
  end subroutine HistoryCreate1

  !-------------------------------------------------------------------

  subroutine HistoryCreate2( &
    & file, title, source, institution, &
    & dims, dimsizes, longnames, units, origin, interval, &
    & xtypes, history, conventions, gt_version, overwrite, quiet, &
    & flag_mpi_gather, flag_mpi_split, err )
    !
    !== gtool4 データ出力用初期設定
    !
    ! このサブルーチンは、gtool4 データ出力の初期設定を行います。
    ! HistoryAddVariable、 HistoryCopyVariable、 HistoryPut、
    ! HistoryAddAttr、 HistoryClose、 HistorySetTime
    ! を用いるためには、HistoryCreate による初期設定が必要です。
    !
    ! なお、プログラム内で HistoryCreate を呼び出した場合、
    ! プログラムを終了する前に必ず、 HistoryClose を呼び出して
    ! 終了処理を行なって下さい。
    !
    ! *HistoryCreate* というサブルーチン名は 2 つの別々の
    ! サブルーチンの総称名です。上記のサブルーチンも参照ください。
    !
    !
    ! Two specific subroutines shares common part:
    !
    ! Both two ones initializes a dataset *file*.
    ! The result of type GT_HISTORY will be returned by *history*
    ! or managed internally if omitted.
    ! Mandatory global attributes are defined by arguments
    ! *title*, *source*, and *institution*;
    ! they are all declared as ((character(len = *))).
    ! Spatial axis definitions have two different forms:
    ! a primitive one uses several arrays of various types:
    ! *dims*, *dimsizes*, *longnames*, *units*, and *xtypes*.
    ! Another sophisticated one has only array of type GT_HISTORY_AXIS,
    ! *axes*.
    ! Temporal definition is done without *origin*, *interval*.
    !
    
    use gtdata_generic,only: Create, put_attr, Get_Attr
    use dc_trace, only: BeginSub, EndSub, DbgMessage
    use dc_error,   only: StoreError, DC_NOERR, GT_EARGSIZEMISMATCH, DC_EALREADYINIT
    use dc_string, only: JoinChar, toChar, StoA
    use dc_url, only: UrlMerge
    use dc_present, only: present_and_not_empty, present_and_false, present_and_true
    use dc_types,   only: STRING, TOKEN, DP
    use dc_message, only: MessageNotify
    use sysdep,     only: SysdepEnvGet
    use dc_date_types, only: DC_DATETIME, DC_DIFFTIME, UNIT_SYMBOL_ERR, UNIT_SYMBOL_SEC
    use dc_date,  only: DCDateTimeCreate, toChar, DCDiffTimeCreate, &
      & EvalByUnit, ParseTimeUnits
    use gtool_history_types, only: GT_HISTORY, GT_HISTORY_AXIS, GT_HISTORY_VARINFO, GT_HISTORY_ATTR
    use gtool_history_internal, only: default
    use gtool_history_generic, only: HistoryCreate
    implicit none
    character(*), intent(in):: file
                              ! 出力するファイルの名前. 
                              ! Name of output file
    character(*), intent(in):: title
                              ! データ全体の表題. 
                              ! Title of entire data
    character(*), intent(in):: source
                              ! データを作成する際の手段. 
                              ! Source of data file
    character(*), intent(in):: institution
                              ! ファイルを最終的に変更した組織/個人. 
                              ! Institution or person that changes files for the last time
    character(*), intent(in):: dims(:)
                              ! 次元の名前. 
                              ! 
                              ! 配列の大きさに制限はありません.
                              ! 個々の次元の文字数は dc_types#TOKEN まで.
                              ! 配列内の文字数は
                              ! 全て同じでなければなりません.
                              ! 足りない文字分は空白で
                              ! 補ってください.
                              ! 
                              ! Names of dimensions.
                              ! 
                              ! Length of array is unlimited. 
                              ! Limits of numbers of characters of each 
                              ! dimensions are "dc_types#TOKEN". 
                              ! Numbers of characters in this array
                              ! must be same. 
                              ! Make up a deficit with blanks. 
                              ! 
    integer, intent(in):: dimsizes (:)
                              ! dims で指定したそれぞれの次元大きさ. 
                              ! 
                              ! 配列の大きさは dims の大きさと等しい
                              ! 必要があります.  '0' (数字のゼロ) を指定
                              ! するとその次元は 無制限次元 (unlimited
                              ! dimension) となります. (gtool_history 
                              ! では時間の次元に対して無制限次元を
                              ! 用いることを想定しています). ただし, 
                              ! 1 つの NetCDF ファイル (バージョン 3) 
                              ! は最大で 1 つの無制限次元しか持てないので, 
                              ! 2 ヶ所以上に '0' を指定しないでください. 
                              ! その場合, 正しく gtool4 データが出力されません.
                              ! 
                              ! Lengths of dimensions specified with "dims". 
                              ! 
                              ! Length of this array must be same as 
                              ! length of "dim".  If '0' (zero) is 
                              ! specified, the dimension is treated as 
                              ! unlimited dimension.  
                              ! (In "gtool_history", unlimited dimension is 
                              ! expected to be used as time). 
                              ! Note that one NetCDF file (version 3) 
                              ! can not have two or more unlimited 
                              ! dimensions, so that do not specify '0' 
                              ! to two or more places. In that case, 
                              ! gtoo4 data is not output currently 
                              ! 
    character(*), intent(in):: longnames (:)
                              ! dims で指定したそれぞれの次元の名前. 
                              !
                              ! 配列の大きさは dims の大きさ
                              ! と等しい必要があります. 文字数
                              ! は dc_types#STRING まで.
                              ! 配列内の文字数は
                              ! 全て同じでなければなりません.
                              ! 足りない文字分は空白で補います.
                              ! 
                              ! Names of dimensions specified with "dims". 
                              !
                              ! Length of this array must be same as 
                              ! length of "dim".  
                              ! Limits of numbers of characters are 
                              ! "dc_types#STRING". 
                              ! Numbers of characters in this array
                              ! must be same. 
                              ! Make up a deficit with blanks. 
                              ! 
    character(*), intent(in):: units(:)
                              ! dims で指定したそれぞれの次元の単位. 
                              !
                              ! 配列の大きさは dims の大きさ
                              ! と等しい必要があります. 文字数
                              ! は dc_types#STRING まで.
                              ! 配列内の文字数は
                              ! 全て同じでなければなりません.
                              ! 足りない文字分は空白で補います.
                              ! 
                              ! Units of dimensions specified with "dims". 
                              !
                              ! Length of this array must be same as 
                              ! length of "dim".  
                              ! Limits of numbers of characters are 
                              ! "dc_types#STRING". 
                              ! Numbers of characters in this array
                              ! must be same. 
                              ! Make up a deficit with blanks. 
                              ! 
    type(DC_DIFFTIME), intent(in):: origin
                              ! 時間の原点. 
                              !
                              ! これは HistoryPut により変数を最初に
                              ! 出力するときの時間となります.
                              ! 
                              ! 省略した場合, 時間の原点には
                              ! 自動的に 0.0 が設定されます.
                              ! 
                              ! Origin of time. 
                              !
                              ! This time is used as time 
                              ! when first output is done by "HistoryPut". 
                              ! 
                              ! If this argument is omitted, 
                              ! 0.0 is specified automatically. 
                              ! 
    type(DC_DIFFTIME), intent(in), optional:: interval
                              ! 出力時間間隔. 
                              !
                              ! 同じ変数に対して HistoryPut が複数回
                              ! 呼ばれた時に, 自動的に時間変数がこの値
                              ! だけ増やされて出力されます. なお, 
                              ! 各々の出力ファイルにつき HistorySetTime
                              ! を一度でも用いた場合, この値は無効に
                              ! なるので注意してください.
                              ! 
                              ! 省略した場合, 自動的に 1.0 が設定されます.
                              ! 
                              ! Interval of output time. 
                              !
                              ! When "HistoryPut" is called two or
                              ! more times for the same variable, time
                              ! is increased as this value and 
                              ! output automatically.
                              ! Note that this value becomes
                              ! invalid when "HistorySetTime" is 
                              ! used for each output file even once.
                              ! 
                              ! If this argument is omitted, 
                              ! 1.0 is specified automatically. 
                              ! 
    character(*), intent(in),  optional:: xtypes(:)
                              ! dims で指定したそれぞれの
                              ! 次元のデータ型. 
                              !
                              ! デフォルトは float (単精度実数型)
                              ! です. 有効なのは,
                              ! double (倍精度実数型), 
                              ! int (整数型) です. 指定しない
                              ! 場合や, 無効な型を指定した場合には,
                              ! float となります. なお, 配列の大きさ
                              ! は *dims* の大きさと等しい必要が
                              ! あります. 配列内の文字数は全て
                              ! 同じでなければなりません.
                              ! 足りない文字分は空白で補います.
                              !
                              ! Data types of dimensions specified 
                              ! with "dims". 
                              !
                              ! Default value is "float" (single precision). 
                              ! Other valid values are 
                              ! "double" (double precision), 
                              ! "int" (integer). 
                              ! If no value or invalid value is specified, 
                              ! "float" is applied. 
                              ! Length of this array must be same as 
                              ! length of "dim".  
                              ! Numbers of characters in this array
                              ! must be same. 
                              ! Make up a deficit with blanks. 
                              ! 
    type(GT_HISTORY), intent(out), optional, target:: history
                              ! 出力ファイルの設定に関する情報を
                              ! 格納した構造体. 
                              !
                              ! 1 つのプログラムで複数のファイル
                              ! に gtool データを出力する
                              ! 場合に利用します.
                              ! (単独のファイルに書き出す場合は
                              ! 指定する必要はありません)
                              ! 
                              ! Derived type that 
                              ! stores information about output files. 
                              !
                              ! If multiple gtool4 data files are 
                              ! output from one program, use this 
                              ! argument. 
                              ! (If onlye one file is output, 
                              ! this argument is not needed). 
                              ! 
    character(*), intent(in), optional:: conventions
                              ! 出力するファイルの netCDF
                              ! 規約
                              !
                              ! 省略した場合,
                              ! もしくは空文字を与えた場合,
                              ! 出力する netCDF 規約の
                              ! Conventions 属性に値
                              ! gtool4_netCDF_Conventions
                              ! が自動的に与えられます.
                              ! 
                              ! NetCDF conventions of output file. 
                              !
                              ! If this argument is omitted or, 
                              ! blanks are given,
                              ! gtool4_netCDF_Conventions is given to 
                              ! attribute "Conventions" of an output file
                              ! automatically. 
                              ! 
    character(*), intent(in), optional:: gt_version
                              ! gtool4 netCDF 規約のバージョン
                              !
                              ! 省略した場合, gt_version 属性に
                              ! 規約の最新版のバージョンナンバー
                              ! gtool4_netCDF_version
                              ! が与えられます.
                              ! (ただし, 引数 conventions に
                              ! gtool4_netCDF_Conventions
                              ! 以外が与えられる場合は
                              ! gt_version 属性を作成しません).
                              ! 
                              ! Version of gtool4 netCDF Conventions. 
                              !
                              ! If this argument is omitted, 
                              ! latest version number of gtool4 netCDF 
                              ! Conventions is given to attribute 
                              ! "gt_version" of an output file 
                              ! (However, gtool4_netCDF_Conventions is 
                              ! not given to an argument "conventions", 
                              ! attribute "gt_version" is not created).
                              ! 
    logical, intent(in), optional:: overwrite
                              ! 上書き可否
                              !
                              ! この引数に .false. を渡すと,
                              ! 既存のファイルを上書きしません.
                              ! デフォルトは上書きします.
                              ! 
                              ! Whether or not to overwrite. 
                              !
                              ! If .false. is specified to this 
                              ! argument, an existing file is not
                              ! overwritten. 
                              ! By default, existing file is overwritten. 
                              ! 
    logical, intent(in), optional:: quiet
                              ! .true. を与えた場合, 
                              ! メッセージ出力が抑制されます. 
                              ! デフォルトは .false. です. 
                              !
                              ! If ".true." is given, 
                              ! messages are suppressed. 
                              ! Default value is ".false.".
                              ! 
    logical, intent(in), optional:: flag_mpi_gather
                              ! MPI 使用時に, 各ノードで HistoryPut
                              ! に与えたデータを一つのファイルに統合して出力
                              ! する場合には .true. を与えてください. 
                              ! デフォルトは .false. です. 
                              ! 
                              ! .true. を与えた場合, HistoryPutAxisMPI
                              ! に全体の軸データを与えてください. 
                              !
                              ! When MPI is used, if ".true." is given, 
                              ! data given to "HistoryPut" on each node
                              ! is integrated and output to one file. 
                              ! Default value is ".false.".
                              ! 
                              ! If .true. is given, give data of axes in
                              ! whole area to "HistoryPutAxisMPI"
                              ! 
    logical, intent(in), optional:: flag_mpi_split
                              ! MPI 使用時にこの引数に .true. を与えると, 
                              ! 各ノードごとに
                              ! *file* 引数に "_rankXXXXXX" 
                              ! (X は [0-9] の数値で, ノード番号を指す) 
                              ! を付加したファイルを出力します. 
                              ! 例えば, *file* に "output.nc" を与えた場合. 
                              ! ノード 0 では "output_rank000000.nc", 
                              ! ノード 12 では "output_rank000012.nc"
                              ! を出力します. 
                              ! デフォルトは .false. です. 
                              !
                              ! When MPI is used, if ".true." is given, 
                              ! files that have names with suffixes
                              ! "_rankXXXXXX" 
                              ! (X is [0-9] that indicates node number) 
                              ! are output on each node. 
                              ! For example, "output.nc" is given to *file*, 
                              ! "output_rank000000.nc", "output_rank000012.nc"
                              ! are output on node 0 and node 12. 
                              ! Default value is ".false.".
                              ! 
    logical, intent(out), optional:: err
                              ! 例外処理用フラグ.
                              ! デフォルトでは, この手続き内でエラーが
                              ! 生じた場合, プログラムは強制終了します.
                              ! 引数 *err* が与えられる場合,
                              ! プログラムは強制終了せず, 代わりに
                              ! *err* に .true. が代入されます.
                              !
                              ! Exception handling flag. 
                              ! By default, when error occur in 
                              ! this procedure, the program aborts. 
                              ! If this *err* argument is given, 
                              ! .true. is substituted to *err* and 
                              ! the program does not abort. 

    type(GT_HISTORY), pointer:: hst =>null()
    real(DP):: origind, intervald
    integer:: i, numdims, blank_index
    character(TOKEN):: unlimited_units
    integer:: unit_symbol
    integer:: stat
    character(STRING):: cause_c
    character(*), parameter:: subname = "HistoryCreate2"
    character(*), parameter:: version = &
      & '$Name:  $' // &
      & '$Id: historycreate.rb2f90,v 1.4 2009-11-03 05:22:46 morikawa Exp $'
  continue
    call BeginSub(subname, 'file=%c ndims=%d',  &
      & c1=trim(file), i=(/size(dims)/), &
      & version=version)
    stat = DC_NOERR
    cause_c = ""

    numdims = size(dims)

    unlimited_units = 'sec'
    do, i = 1, numdims
      if (dimsizes(i) == 0) unlimited_units = units(i)
    end do

    blank_index = index( trim( adjustl(unlimited_units) ), ' ' )
    if ( blank_index > 1  ) then
      unlimited_units = unlimited_units(1:blank_index-1)
    end if

    unit_symbol = ParseTimeUnits( unlimited_units )
    if ( unit_symbol == UNIT_SYMBOL_ERR ) unit_symbol = UNIT_SYMBOL_SEC

    if (present(interval)) then
      intervald = EvalByUnit( interval, '', unit_symbol )
    else
      intervald = 1.0_DP
    end if

    origind = EvalByUnit( origin, '', unit_symbol )

    call HistoryCreate( & 
      & file = file, title = title, &
      & source = source, institution = institution, &
      & dims = dims, dimsizes = dimsizes, &
      & longnames = longnames, units = units, &
      & xtypes = xtypes, history = history, &
      & origind = origind, intervald = intervald, &
      & conventions = conventions, gt_version = gt_version, &
      & overwrite = overwrite, quiet = quiet, &
      & flag_mpi_gather = flag_mpi_gather, flag_mpi_split = flag_mpi_split, &
      & err = err )

    if (present(history)) then
      hst => history
    else
      hst => default
    endif

999 continue
    call StoreError(stat, subname, cause_c=cause_c)
    call EndSub(subname, 'stat=%d', i = (/stat/) )
  end subroutine HistoryCreate2

  !-------------------------------------------------------------------

  subroutine HistoryCreate3(file, title, source, institution, &
    & axes, origin, interval, history, origind, intervald, conventions, gt_version, &
    & overwrite, quiet, flag_mpi_gather, flag_mpi_split, err )
    !
    !== gtool4 データ出力用初期設定
    !
    ! *HistoryCreate* というサブルーチン名は 2 つの別々の
    ! サブルーチンの総称名です。まずは HistoryCreate を参照ください。
    !
    ! もう 1 つのサブルーチンと異なる点は、座標軸の情報を
    ! *dims*, *dimsizes*, *longnames*, *units*, and *xtypes* といった
    ! 個別の引数で与えるのではなく、構造体 GT_HISTORY_AXIS 型の
    ! 引数 *axes* で与える点にあります。
    !
    ! GT_HISTORY_AXIS 型変数の生成 (constructer) は
    ! HistoryAxisCreate にて行います。
    !
    !
    ! Two specific subroutines shares common part:
    !
    ! Both two ones initializes a dataset *file*.
    ! The result of type GT_HISTORY will be returned by *history*
    ! or managed internally if omitted.
    ! Mandatory global attributes are defined by arguments
    ! *title*, *source*, and *institution*;
    ! they are all declared as ((character(len = *))).
    ! Spatial axis definitions have two different forms:
    ! a primitive one uses several arrays of various types:
    ! *dims*, *dimsizes*, *longnames*, *units*, and *xtypes*.
    ! Another sophisticated one has only array of type GT_HISTORY_AXIS,
    ! *axes*.
    ! Temporal definition is done without *origin*, *interval*.
    !
    use dc_types,   only: STRING, TOKEN, DP
    use dc_present, only: present_and_true
    use dc_trace, only: BeginSub, EndSub, DbgMessage
    use gtool_history_generic, only: HistoryCreate
    use gtool_history_types, only: GT_HISTORY, GT_HISTORY_AXIS, GT_HISTORY_VARINFO, GT_HISTORY_ATTR
    use gtool_history_internal, only: default, copy_attrs, append_attrs
    implicit none
    character(*), intent(in):: file
                              ! HistoryCreate 参照
                              ! (以下 axes を除く引数も同様)
                              !
    character(*), intent(in):: title, source, institution
    type(GT_HISTORY_AXIS), intent(in):: axes(:)
                              ! 次元情報を格納した構造型変数
                              !
                              ! GT_HISTORY_AXIS 型変数の生成
                              ! (constructer) は
                              ! HistoryAxisCreate にて行いま
                              ! す。配列の大きさに制限は
                              ! ありません。
                              !
    real, intent(in), optional:: origin, interval
    type(GT_HISTORY), intent(out), optional, target:: history
    real(DP), intent(in), optional:: origind, intervald
    character(*), intent(in),  optional:: conventions, gt_version
    logical, intent(in), optional:: overwrite
    logical, intent(in), optional:: quiet
                              ! .true. を与えた場合, 
                              ! メッセージ出力が抑制されます. 
                              ! デフォルトは .false. です. 
                              !
                              ! If ".true." is given, 
                              ! messages are suppressed. 
                              ! Default value is ".false.".
                              ! 
    logical, intent(in), optional:: flag_mpi_gather
                              ! MPI 使用時に, 各ノードで HistoryPut
                              ! に与えたデータを一つのファイルに統合して出力
                              ! する場合には .true. を与えてください. 
                              ! デフォルトは .false. です. 
                              ! 
                              ! .true. を与えた場合, HistoryPutAxisMPI
                              ! に全体の軸データを与えてください. 
                              !
                              ! When MPI is used, if ".true." is given, 
                              ! data given to "HistoryPut" on each node
                              ! is integrated and output to one file. 
                              ! Default value is ".false.".
                              ! 
                              ! If .true. is given, give data of axes in
                              ! whole area to "HistoryPutAxisMPI"
                              ! 
    logical, intent(in), optional:: flag_mpi_split
                              ! MPI 使用時にこの引数に .true. を与えると, 
                              ! 各ノードごとに
                              ! *file* 引数に "_rankXXXXXX" 
                              ! (X は [0-9] の数値で, ノード番号を指す) 
                              ! を付加したファイルを出力します. 
                              ! 例えば, *file* に "output.nc" を与えた場合. 
                              ! ノード 0 では "output_rank000000.nc", 
                              ! ノード 12 では "output_rank000012.nc"
                              ! を出力します. 
                              ! デフォルトは .false. です. 
                              !
                              ! When MPI is used, if ".true." is given, 
                              ! files that have names with suffixes
                              ! "_rankXXXXXX" 
                              ! (X is [0-9] that indicates node number) 
                              ! are output on each node. 
                              ! For example, "output.nc" is given to *file*, 
                              ! "output_rank000000.nc", "output_rank000012.nc"
                              ! are output on node 0 and node 12. 
                              ! Default value is ".false.".
                              ! 
    logical, intent(out), optional:: err
                              ! 例外処理用フラグ.
                              ! デフォルトでは, この手続き内でエラーが
                              ! 生じた場合, プログラムは強制終了します.
                              ! 引数 *err* が与えられる場合,
                              ! プログラムは強制終了せず, 代わりに
                              ! *err* に .true. が代入されます.
                              !
                              ! Exception handling flag. 
                              ! By default, when error occur in 
                              ! this procedure, the program aborts. 
                              ! If this *err* argument is given, 
                              ! .true. is substituted to *err* and 
                              ! the program does not abort. 


    ! 構造体 GT_HISTORY_AXIS のデータ蓄積用
    character(STRING), allocatable:: axes_name(:)
    integer          , allocatable:: axes_length(:)
    character(STRING), allocatable:: axes_longname(:)
    character(STRING), allocatable:: axes_units(:)
    character(STRING), allocatable:: axes_xtype(:)

    integer:: i, ndims
#ifdef LIB_MPI
    type(GT_HISTORY), pointer:: hst =>null()
    integer:: attr_size
#endif
    character(len = *), parameter:: subname = "HistoryCreate3"
  continue
    call BeginSub(subname, 'file=%c ndims=%d', &
      & c1=trim(file), i=(/size(axes)/) )

    ! 構造体 GT_HISTORY_AXIS の axes からのデータ取得
    !   (Fujitsu Fortran などなら axes(:)%name という表記で配列
    !    データをそのまま引き渡せるが、Intel Fortran 8 などだと
    !    その表記をまともに解釈してくれないので、美しくないけど
    !    いったん他の配列に情報を引き渡す)。2004/11/27 morikawa
    ndims = size( axes(:) )
    allocate( axes_name(ndims) )
    allocate( axes_length(ndims) )
    allocate( axes_longname(ndims) )
    allocate( axes_units(ndims) )
    allocate( axes_xtype(ndims) )

    do i = 1, ndims
      axes_name(i)     = axes(i) % name
      axes_length(i)   = axes(i) % length
      axes_longname(i) = axes(i) % longname
      axes_units(i)    = axes(i) % units
      axes_xtype(i)    = axes(i) % xtype

      call DbgMessage('axes(%d):name=<%c>, length=<%d>, ' // & 
        &             'longname=<%c>, units=<%c>'     , &
        &              i=(/i, axes(i) % length/)        , &
        &              c1=( trim(axes(i) % name) )      , &
        &              c2=( trim(axes(i) % longname) )  , &
        &              c3=( trim(axes(i) % units) )    )
    enddo

    call HistoryCreate(file, title, source, institution, &
      & dims = axes_name(:), dimsizes = axes_length(:), &
      & longnames = axes_longname(:), units = axes_units(:), &
      & xtypes = axes_xtype(:), &
      & origin = origin, interval = interval, &
      & history = history, &
      & origind = origind, intervald = intervald, &
      & conventions = conventions, &
      & gt_version = gt_version, overwrite = overwrite, quiet = quiet, &
      & flag_mpi_gather = flag_mpi_gather, &
      & flag_mpi_split = flag_mpi_split, &
      & err = err )

    deallocate( axes_name )
    deallocate( axes_length )
    deallocate( axes_longname )
    deallocate( axes_units )
    deallocate( axes_xtype )

#ifdef LIB_MPI
    if ( .not. present_and_true( flag_mpi_gather ) ) then
#endif

    do i = 1, ndims
      if ( .not. associated( axes(i) % attrs ) ) cycle
      call append_attrs( axes(i) % name, axes(i) % attrs, history )
    end do

#ifdef LIB_MPI
    else

    if (present(history)) then
      hst => history
    else
      hst => default
    endif

    do i = 1, ndims
      if ( .not. associated( axes(i) % attrs ) ) cycle
      attr_size = size( axes(i) % attrs )
      allocate( hst % mpi_dimdata_all(i) % attrs( attr_size ) )
      call copy_attrs( from = axes(i) % attrs, &
        &                to = hst % mpi_dimdata_all(i) % attrs )
    end do

    endif
#endif

    call EndSub(subname)
  end subroutine HistoryCreate3

!--
! vi:set readonly sw=4 ts=8:
!
!Local Variables:
!mode: f90
!buffer-read-only: t
!End:
!
!++
