!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
begin procedure mosaic-pattern-def
  ! 
  ! Computes offsets for a mosaic
  ! - exact mosaic pattern
  ! - there is always a field in (0,0) 
  !        => odd number of fields in each direction 
  !
  define integer nra ndec kfield
  define double size_ra size_dec first_ra first_dec delta_ra delta_dec
  define double ra_off dec_off lambda
  define logical even jeven
  !
  let lambda 299792458/(mos%freq*1e9)
  let mos%primbeam 1.2*lambda/mos%diam/sec ! *** JP unclear whether the 1.2 should be there
  ! Deletes the offset arrays and redefines them later as global variables 
  ! with the right dimension
  if (exist(mos%xoff)) then
     delete /var mos%xoff
  endif
  if (exist(mos%yoff)) then
     delete /var mos%yoff
  endif
  let size_ra  mos%size[1]
  let size_dec mos%size[2]
  ! Computes pixel size to obtain an mosaic pattern
  let delta_ra  0.5*mos%primbeam
  let delta_dec 0.25*sqrt(3.0)*mos%primbeam
  ! `nra' and `ndec' are the number of beams the mosaic will have in ra 
  ! and dec. These must at least be 1
  let nra  max(1,int(size_ra/(2.0*delta_ra)))
  let ndec max(1,int(size_dec/(2.0*delta_dec)))
  ! `first_ra' and `first_dec' are the coordiantes of the first 
  ! pointing position
  let first_ra    (nra-1)*delta_ra
  let first_dec -(ndec-1)*delta_dec
  ! Finds position of fields in ra and dec
  define double xoff['2*nra-1'] yoff['2*ndec-1']
  for i 0 to 2*nra-2
     let xoff['i+1'] first_ra-delta_ra*i
  next
  for j 0 to 2*ndec-2
     let yoff['j+1'] first_dec+delta_dec*j
  next
  ! Here is the hard part
  !  - Tries to make a good use of the fact that an mosaic pattern 
  !    is asymetric in ra and dec;
  ! That probably can be done in a more elegant way but that is working!
  let kfield 1
  let even (2*int(ndec/2).eq.ndec)
  if (even) then 
     let mos%nfield (2*nra-2)*ndec+(2*nra-1)*(ndec-1)
  else
     let mos%nfield (2*nra-2)*(ndec-1)+(2*nra-1)*ndec
  endif
  define double mos%xoff[mos%nfield] mos%yoff[mos%nfield] /global
  let ra_off 0.5*delta_ra
  for jfield 1 to 2*ndec-1
     let jeven (2*int(jfield/2).eq.jfield)
     if ((even.and.jeven).or.((.not.even).and.(.not.jeven))) then
        for ifield 1 to 2*nra-1
           let mos%xoff[kfield] xoff[ifield]
           let mos%yoff[kfield] yoff[jfield]
           let kfield kfield+1
        next ifield
     else
        for ifield 1 to 2*nra-2
           let mos%xoff[kfield] xoff[ifield]-ra_off
           let mos%yoff[kfield] yoff[jfield]
           let kfield kfield+1
        next ifield
     endif
  next jfield
  ! When asked, selects only the fields which are in a circular region 
  ! (i.e. the closest neighbours of the central field)
  if (mos%closest) then
     define double new_xoff[mos%nfield] new_yoff[mos%nfield]
     define double circular_limit
     ! The 1.01 factor comes from rounding problems
     let circular_limit (1.01*(nra-1)*delta_ra)^2
     let kfield 1
     for ifield 1 to mos%nfield
        say 'circular_limit' 'mos%xoff[ifield]^2+mos%yoff[ifield]^2'
        if ((mos%xoff[ifield]^2+mos%yoff[ifield]^2).le.circular_limit) then
           let new_xoff[kfield] mos%xoff[ifield]
           let new_yoff[kfield] mos%yoff[ifield]
           let kfield kfield+1
        endif
     next ifield
     delete /var mos%xoff mos%yoff
     let mos%nfield kfield-1
     define double mos%xoff[mos%nfield] mos%yoff[mos%nfield] /global
     let mos%xoff new_xoff[1:mos%nfield]
     let mos%yoff new_yoff[1:mos%nfield]
     delete /var new_xoff new_yoff
  endif
  exa mos%nfield
  ! Rotate the coordinates
  define double new_xoff[mos%nfield] new_yoff[mos%nfield]
  define double pha cospha sinpha
  let pha mos%orien*pi/180
  let cospha cos(pha)
  let sinpha sin(pha)
  let new_xoff mos%xoff*cospha-mos%yoff*sinpha
  let new_yoff mos%xoff*sinpha+mos%yoff*cospha
  let mos%xoff new_xoff
  let mos%yoff new_yoff
  delete /var new_xoff new_yoff
  ! Offset the coordinates
  let mos%xoff mos%xoff+mos%center[1]
  let mos%yoff mos%yoff+mos%center[2]
  !
end procedure mosaic-pattern-def
!
begin procedure mosaic-pattern-plot
  ! Plot fields
  g\set marker 4 1 0.4 45
  pen 'mos%pen'
  for ifield 1 to mos%nfield
     ellipse 'mos%primbeam/2' /user 'mos%xoff[ifield]' 'mos%yoff[ifield]' sec 
  next ! ifield
  ! Plot box that define the mosaic size
  @ p-poly rectangle 'mos%center[1]' 'mos%center[2]' 'mos%size[1]' 'mos%size[2]' '90-mos%orien'
  pen 0
end procedure mosaic-pattern-plot
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
if .not.exist(mos) then
   define structure mos /global
   define double mos%freq mos%diam mos%primbeam /global
   define double mos%orien mos%size[2] mos%center[2] /global
   define logical mos%closest /global
   define integer mos%nfield mos%pen /global
   let mos%closest yes
   let mos%orien 0.0
   let mos%size 400.0
   let mos%center 0
   let mos%freq 115.5
   let mos%diam 15
   let mos%nfield 0
   let mos%pen 1
endif
!
@ mosaic-pattern-def
@ mosaic-pattern-plot
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

