subroutine nbi_3dhalo_write(filename)
  use iso_c_binding, only: fp => c_double
  use logmod
  use netcdf
  use nbi_halo_mod_def
  implicit none
  character*(*) filename
  integer :: icdf
  integer :: i,isize_trk
  integer :: irbuf !size r8 data in 3d halo module
  integer :: iibuf !size int data in 3d halo module
  integer :: ichar !character size in 3d halo module
  character*30 :: cvar
  character*5 :: c_buf(1)
  integer, dimension(1) :: idims,istart,icount
  integer, dimension(2) :: istart2,icount2
  integer :: id_isizetrk,id_maxpts,id_irbuf,id_iibuf,id_ichar,id_rbuf,id_ibuf,id_cbuf
  integer :: ierr,isizetrk,izones,i_buf(7),ii
  real(fp) :: r_buf(10)
  
  !prepare 3d neutral track to be written on a disk
  !if track has 0 nzcrtk (number of box zones intercepted by track) then this track will be excluded
  ierr=0
  isize_trk=size(itrackh_rqinit) !how many track has been initialize in all
  isizetrk=0 !counter for a # of track that has been stored
  izones=0 !# zones that have been intercept by all stored tracks
  do i=1,isize_trk
     if(itrackh_rqinit(i))cycle
     if(itrackh(i)%idgen.lt.0) cycle
     if(itrackh(i)%maxpts.le.0) cycle
     if(itrackh(i)%izone_pl(2).le.0) cycle
     isizetrk=isizetrk+1
     izones=izones+itrackh(i)%maxpts
  enddo
  
  irbuf=10*isizetrk+3*izones
  iibuf= 7*isizetrk
  ichar= 5

  call check(nf90_create(path=trim(adjustl(filename)),&
       & cmode= or(nf90_clobber,nf90_64bit_offset),&
       & ncid=icdf),trim(adjustl(filename)))
  cvar='isize_trk'
  call check(nf90_def_dim(icdf,cvar,isizetrk,id_isizetrk),cvar)
  cvar='irbuf'
  call check(nf90_def_dim(icdf,cvar,irbuf,id_irbuf),cvar)
  cvar='iibuf'
  call check(nf90_def_dim(icdf,cvar,iibuf,id_iibuf),cvar)
  cvar='ichar'
  call check(nf90_def_dim(icdf,cvar,ichar,id_ichar),cvar)
  
  cvar = 'ibuf'
  idims = (/id_iibuf/)
  call check(nf90_def_var(icdf,cvar,nf90_int,idims,id_ibuf),cvar)
  cvar = 'rbuf'
  idims = (/id_irbuf/)
  call check(nf90_def_var(icdf,cvar,nf90_double,idims,id_rbuf),cvar)
  cvar = 'cbuf'
  call check(nf90_def_var(icdf,cvar,nf90_char,(/id_ichar,id_isizetrk/),id_cbuf),cvar)
  ierr = nf90_enddef(icdf) ! out of def mode and go to data mode
  if(ierr.ne.0) then
     call errorlog(' nbi_3dhalo_write: isize_trk=',isize_trk)
     call errorlog(' nbi_3dhalo_write: isizetrk=',isizetrk)
     call errorlog(' nbi_3dhalo_write: failed to exit from define mode')
     call errorlog(' nbi_3dhalo_write: ierr=',ierr)
     call bad_exit
  endif
  
  cvar = 'ibuf'
  
  istart(1)=1
  icount(1)=7
  do i=1,isize_trk
     if(itrackh_rqinit(i))cycle
     if(itrackh(i)%idgen.lt.0) cycle
     if(itrackh(i)%maxpts.le.0) cycle
     if(itrackh(i)%izone_pl(2).le.0) cycle
     i_buf(1:7)=(/itrackh(i)%maxpts,itrackh(i)%idbox,itrackh(i)%izone_pl(1),&
          & itrackh(i)%izone_pl(2),itrackh(i)%idgen,itrackh(i)%ipitch,itrackh(i)%igyro/)
     call check( nf90_put_var(icdf,id_ibuf,i_buf(1:7),start=istart,count=icount),cvar)
     istart(1)=istart(1)+icount(1)
  enddo
  ii=0
  istart(1)=1
  do i=1,isize_trk
     if(itrackh_rqinit(i))cycle
     if(itrackh(i)%idgen.lt.0) cycle
     if(itrackh(i)%maxpts.le.0) cycle
     if(itrackh(i)%izone_pl(2).le.0) cycle
     ii=ii+1
     icount(1)=10
     r_buf(1:10)=(/itrackh(i)%weight,itrackh(i)%zspecies,itrackh(i)%aspecies,&
          & itrackh(i)%vneut,itrackh(i)%pta(1:3),itrackh(i)%ptb(1:3)/)
     call check( nf90_put_var(icdf,id_rbuf,r_buf(1:10),start=istart,count=icount),cvar)
     istart(1)=istart(1)+icount(1)
     icount(1)=itrackh(i)%maxpts
     call check( nf90_put_var(icdf,id_rbuf,itrackh(i)%xlngtk(1:icount(1)),start=istart,count=icount),cvar)
     istart(1)=istart(1)+icount(1)
     call check( nf90_put_var(icdf,id_rbuf,itrackh(i)%pdep(1:icount(1)),start=istart,count=icount),cvar)
     istart(1)=istart(1)+icount(1)
     call check( nf90_put_var(icdf,id_rbuf,itrackh(i)%dkappa(1:icount(1)),start=istart,count=icount),cvar)
     istart(1)=istart(1)+icount(1)
  enddo
  icount2(1)=5
  istart2(1)=1
  icount2(2)=1
  istart2(2)=1
  do i=1,isize_trk
     if(itrackh_rqinit(i))cycle
     if(itrackh(i)%idgen.lt.0) cycle
     if(itrackh(i)%maxpts.le.0) cycle
     if(itrackh(i)%izone_pl(2).le.0) cycle
     c_buf(1)=itrackh(i)%type
     call check( nf90_put_var(icdf,id_cbuf,c_buf,start=(/istart2(1),istart2(2)/),&
          & count=(/icount2(1),icount2(2)/)),cvar)
     istart2(2)=istart2(2)+icount2(2)
  enddo
  ierr = nf90_close( icdf)
  if(ierr.ne.0) then
     call errorlog(' nbi_bs_write: netcdf close failure '//trim(filename))
     call bad_exit("nbi_bs_write :  cannot create file")
  endif
  
  
contains 
  subroutine check(status,varnam)
    integer, intent ( in) :: status 
    character*(*),intent(in) :: varnam ! dimension name input 
    
    if(status /= nf90_noerr) then 
       call errorlog(' nbi_3dhalo_write: error:'& 
            &// trim(nf90_strerror(status))//' for var.= '//trim(varnam))
       call bad_exit 
    end if
  end subroutine check
  
end subroutine nbi_3dhalo_write
