subroutine nbo_output_all(ierr)

  ! (a) write xplasma file (named by nbo_output_file)
  ! (b) write scalars file & file with output profile names (nbo_outputs call)

  use nbi_com
  implicit none

  integer, intent(out) :: ierr

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

  character*250 zfile

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

  call nbo_output_file('xplasma',zfile)

  call eq_save(trim(zfile),ierr)
  if(ierr.ne.0) then
     write(nonlin,*) ' ?nbo_output_all: xplasma write failed!'
     return
  endif

  call nbo_output_file('scalars',zfile)

  call nbo_outputs(trim(zfile),'W',ierr)
  if(ierr.ne.0) then
     write(nonlin,*) ' ?nbo_output_all: write of scalars failed!'
     return
  endif

end subroutine nbo_output_all

subroutine nbo_output_file(ztype,zname)

  !  return a filename:
  !    "xplasma" -> trim(workpath)//trim(runid)_xplasma_out.cdf

  !    "scalars" -> trim(workpath)//trim(runid)_scalars_out.cdf

  !  case blind compare of 1st two letters is used: sc or xp.

  !  no match => zname = "??-error"
  use nbi_com
  implicit none

  character*(*), intent(in) :: ztype
  character*(*), intent(out) :: zname

  !-----------------------
  character*2 :: ztest
  integer :: ic,icd,ics,ilen
  !-----------------------

  ztest=ztype(1:2)
  call uupper(ztest)

  if(ztest.eq.'XP') then
     zname = trim(workpath)//trim(runid)//'_xplasma_out.cdf'
     return

  else if(ztest.eq.'SC') then

     zname = trim(workpath)//trim(runid)//'_scalars_out.cdf'
     return

  else

     zname = '??-error'

  endif

end subroutine nbo_output_file

subroutine nbo_outputs(filename,action,ierr)

  ! read or write (non-xplasma) output data from nubeam calculation.
  ! mod dmc apr 2008 -- names of profiles (instead of integer ids)
  ! are written out

  use nbi_com
  use ezcdf

  implicit none

  character*(*), intent(in) :: filename   ! filename of file to read or write
  character*1, intent(in) :: action   ! "w" or "w": write, "r" or "r": restore

  integer, intent(out) :: ierr        ! completion code: 0 = ok

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

  integer :: icdf                     ! netcdf channel id
  integer :: ilun

  character*1 actup
  character*250 loc_filenam
  !---------------------------------------------------

  call gen_loc_filenam

  actup=action
  call uupper(actup)

  ierr=0

  if(actup.eq.'W') then
     
     ! write...

     call ezcdf_open(icdf,filename,'W',ierr)
     if(ierr.ne.0) then
        write(nonlin,*) ' ?nbo_outputs(...,"w",...) ezcdf_open: ierr= ',ierr
     else

        call nbo_outputs_write(icdf)
        call ezcdf_close(icdf)

     endif
     if(ierr.ne.0) return

     call find_io_unit(ilun)
     open(unit=ilun,file=trim(loc_filenam),status='unknown',iostat=ierr)
     if(ierr.ne.0) then
        write(nonlin,*) &
             ' ?nbo_outputs(...,"w",...) could not open ascii prof names file:'
        write(nonlin,*) '  '//trim(loc_filenam)
        return
     endif

     call nbo_names_write(ilun)
     close(unit=ilun)

  else if(actup.eq.'R') then

     ! read...

     call ezcdf_open(icdf,filename,'R',ierr)
     if(ierr.ne.0) then
        write(nonlin,*) ' ?nbo_outputs(...,"r",...) ezcdf_open: ierr= ',ierr
     else

        call nbo_outputs_read(icdf,ierr)
        call ezcdf_close(icdf)

        if(ierr.ne.0) then
           write(nonlin,*) ' ?nbo_outputs(...,"R",...): netcdf file read error.'
           write(nonlin,*) '  file may be from a different version of nubeam.'
        endif

     endif
     if(ierr.ne.0) return

     call find_io_unit(ilun)
     open(unit=ilun,file=trim(loc_filenam),status='old',iostat=ierr)
     if(ierr.ne.0) then
        write(nonlin,*) &
             ' ?nbo_outputs(...,"r",...) could not open ascii prof names file:'
        write(nonlin,*) '  '//trim(loc_filenam)
        return
     endif

     call nbo_names_read(ilun,ierr)
     if(ierr.ne.0) then
        write(nonlin,*) &
             ' ?nbo_outputs(...,"r",...) unexpected read error, prof names file:'
        write(nonlin,*) '  '//trim(loc_filenam)
     endif
     close(unit=ilun)

  endif

contains
  subroutine gen_loc_filenam

    integer :: ic,icd,ics,ilen

    ilen=len(trim(filename))
    loc_filenam=filename

    icd=0
    ics=0
    do ic=ilen,1,-1
       if(filename(ic:ic).eq.'.') then
          icd=ic
          exit
       endif
       if(filename(ic:ic).eq.'/') then
          ics=ic
          exit
       endif
    enddo

    if(icd.eq.0) then
       icd=ilen+1
    endif

    loc_filenam(icd:) = '.pnames'

  end subroutine gen_loc_filenam

end subroutine nbo_outputs

subroutine nbo_output_avg(filename,zwght,ierr)

  ! create a modified scalar outputs file, which averages the current
  ! contents of nbi_com with weight (zwght) and the prior contents with
  ! weight (1-zwght).  the idea is to provide a means of creating a time
  ! averaged output file.


  use nbi_com
  use ezcdf

  implicit none

  character*(*), intent(in) :: filename   ! filename of file to modify
  real(fp), intent(in) :: zwght         ! weight factor for new data
  !  note zwght must be between 0.0 and 1.0

  integer, intent(out) :: ierr        ! completion code: 0 = ok

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

  integer :: icdf                     ! netcdf channel id
  !---------------------------------------------------

  ierr = 0
  if((zwght.lt.zero).or.(zwght.gt.one)) then
     write(nonlin,*) ' ?nbo_output_avg: weighting factor zwght = ', &
          zwght,' not between 0 and 1'
     ierr = 1
     return
  endif

  call ezcdf_open(icdf,filename,'m',ierr)
  if(ierr.ne.0) then
     write(nonlin,*) ' ?nbo_output_avg(...) ezcdf_open: ierr= ',ierr
  else

     call nbo_outputs_avg_all(icdf,zwght,ierr)
     call ezcdf_close(icdf)

     if(ierr.ne.0) then
        write(nonlin,*) ' ?nbo_output_avg(...): netcdf i/o ierr= ',ierr
     endif
  endif

end subroutine nbo_output_avg
