;+
;________________________________________________________________________________________________________________________
;
; p2sw_polar_map : mapping d'une image de coordonnees cartesiennes (x, y) en coordonnees polaires (rho, theta).
;________________________________________________________________________________________________________________________
;
; Appel : mapped = p2sw_polar_map(img, theta_size, rho_size, xcenter, ycenter, theta_min, theta_max, amin , amax)
;    ou : mapped = p2sw_polar_map(img, theta_size, rho_size, xcenter, ycenter, theta_min, theta_max, amin , amax, bmin, bmax, psi)
;
; Resultat : tableau de dimensions [theta_size, rho_size] contenant l'image mappee.
;
; Parametres : img : image source, ie tableau 2D de dimensions quelconques et de type simple (fix, long, float, double).
;              out_xsize : taille en x de l'image de sortie.
;              out_ysize : taille en y de l'image de sortie.
;              amin : borne inferieure des valeurs de rho pour le cercle ou le premier axe de l'ellipse.
;              amax : borne superieure des valeurs de rho pour le cercle ou le premier axe de l'ellipse.
;              bmin : borne inferieure des valeurs de rho pour le second axe de l'ellipse
;              bmax : borne superieure des valeurs de rho pour le second axe de l'ellipse
;              theta_min : borne inferieure des valeurs de theta.
;              theta_max : borne superieure des valeurs de theta.
;              x_center : abscisse du centre de la transformation.
;              y_center : ordonnee du centre de la transformation. 
;
; Keywords : missing : si present, les pixels hors de l'image source sont remplaces par missing (1 par defaut).
;                      si absent, les bords de l'image source sont repliques dans les pixels hors de l'image source.
;            cubic : si absent, on utilise l'approximation du plus proche voisin pour evaluer la valeur de chaque pixel.  
;                    si present, on utilise l'interpolation bicubique pour evaluer la valeur de chaque pixel.  
;            bilin : si absent, on utilise l'approximation du plus proche voisin pour evaluer la valeur de chaque pixel.  
;                    si present, on utilise l'interpolation bilineaire pour evaluer la valeur de chaque pixel.  
;            conformal : si absent, utilise une echelle lineaire en y.  
;                        si present, utilise une echelle logarithmique en y, ce qui donne une transformation conforme.  
;            inverse : si absent, passe de cartesiennes a polaires.  
;                      si present, passe de polaires a cartesiennes.  
;________________________________________________________________________________________________________________________
;
; Remarques : Toutes les parametres sont compris en unites de l'image, i.e. en pixels.
;             Les angles sont compris en degres, dans le sens des aiguilles d'une montre, 
;             a partir du haut de l'image.
;             Si cubic et bilin sont presents, l'interpolation bicubique est utilisee.
;             Si amin et amax seuls sont transmis, la transformation est circulaire. Si bmin, bmax et psi sont transmis,
;             la transformation est ellipsoidale.
;________________________________________________________________________________________________________________________
;
; Exemple : x = (findgen(512) # replicate(1.0, 512)) - 256
;           y = (replicate(1.0, 512) # findgen(512)) - 256
;           image = 181-((sqrt(x^2 + y^2)) > 180) < 181)                                                      
;           mapped = p2sw_polar_map(image, 400, 300, 0, 300, 0, 360, 256, 256, missing=0, /bilin)    
;________________________________________________________________________________________________________________________
;
; Historique : 04/06/1997
;              30/06/1997 : Bug coordonnees +-1 selon missing ou non fixe.
;                           Possibilite de mettre missing a 0.
;                           Ajout de l'interpolation bicubique. 
;              02/07/1997 : Missing = 0 : pas de remplissage.                  
;              07/07/1997 : Acceleration du remplissage pour tous les cas de missing. 
;              11/03/1998 : Ajout du keyword conform pour transformation conforme (i.e. echelle log en y).
;              12/03/1998 : Bug modification de x_center, y_center fixe.
;              21/10/1998 : optimisation dans les cas ou missing est present.
;                           ne change plus le type de tableau.
;              22/10/1998 : modification du calcul de rho dans le cas de /conformal.
;              05/11/1998 : modification pour le cas de transformation ellipsoidale.
;              06/11/1998 
;              07/17/2000 : ajout du keyword /inverse
;              23/09/2010 : Improved interpolation to use cubic = -0.5 (dbs)
;________________________________________________________________________________________________________________________
;-

function p2sw_polar_map, img, out_xsize, out_ysize, x_center, y_center, theta_min, theta_max, amin, amax, bmin, bmax, psi, $
                              missing=missing, bilin=bilin, cubic=cubic, conformal=conformal, inverse=inverse
   
   
  if keyword_set(inverse) then begin
  
    x = (findgen(out_xsize) - x_center) # replicate(1.0, out_ysize)
    y = replicate(1.0, out_xsize) # (findgen(out_ysize) - y_center)
  
    rho = sqrt(x^2.0 + y^2.0)
    theta = !radeg*(!pi - atan(x, -y))
  
    sz = size(img)
    theta_size = sz[1]
    rho_size = sz[2]
  
    theta = theta_size*(theta - theta_min)/(theta_max - theta_min)
    rho = rho_size*(rho - amin)/(amax - amin)

    if n_elements(missing) ne 0 then begin
      if keyword_set(cubic) then return, interpolate(img, 0>theta<(theta_size-1), rho, cubic=-0.5, missing=missing) else $
      if keyword_set(bilin) then return, interpolate(img, 0>theta<(theta_size-1), rho, missing=missing) else $
      begin
       image = make_array(size=sz+[0, 2, 2, 0, 0], value=missing)
       image[1, 1] = img
       return, image[1>round(theta+1)<(theta_size-1), 0>round(rho+1)<(rho_size+1)]
     endelse
    endif else begin
      if keyword_set(cubic) then return, interpolate(img, 0>theta<(theta_size-1), 0>rho<(rho_size-1), cubic=-0.5) else $
      if keyword_set(bilin) then return, interpolate(img, 0>theta<(theta_size-1), 0>rho<(rho_size-1)) else $
                                 return, img[0>round(theta)<(theta_size-1), 0>round(rho)<(rho_size-1)]
    endelse
  
  endif else begin 
   
    if n_params() eq 9 then begin
      if keyword_set(conformal) then rho = amin + (amax - amin) * alog(findgen(out_ysize)>1) / alog(out_ysize) else $
      rho = amin + (amax - amin) * findgen(out_ysize) / out_ysize
      theta = (theta_min + findgen(out_xsize) * (theta_max - theta_min) / out_xsize) * !pi / 180.0

      x = (sin(theta) # rho) + x_center 
      y = (cos(theta) # rho) + y_center 
    endif else begin
      if keyword_set(conformal) then begin
        arho = amin + (amax - amin) * alog(findgen(out_ysize)>1) / alog(out_ysize)
        brho = bmin + (bmax - bmin) * alog(findgen(out_ysize)>1) / alog(out_ysize)
      endif else begin
        arho = amin + (amax - amin) * findgen(out_ysize) / out_ysize
        brho = bmin + (bmax - bmin) * findgen(out_ysize) / out_ysize
      endelse
  
      thetapsi = (theta_min + dindgen(out_xsize) * (theta_max - theta_min) / out_xsize - psi) * !pi / 180.0

      x = ((sin(thetapsi)*cos(!pi*psi/180.0)) # arho) + ((cos(thetapsi)*sin(!pi*psi/180.0)) # brho) + x_center 
      y = ((cos(thetapsi)*cos(!pi*psi/180.0)) # brho) - ((sin(thetapsi)*sin(!pi*psi/180.0)) # arho) + y_center 
    endelse
   
    if n_elements(missing) ne 0 then begin
      if keyword_set(cubic) then return, interpolate(img, x, y, cubic=-0.5, missing=missing) else $
      if keyword_set(bilin) then return, interpolate(img, x, y, missing=missing) else $
      begin
        image = make_array(size=size(img)+[0, 2, 2, 0, 0], value=missing)
        image(1, 1) = img
        return, image(round(x+1.0), round(y+1.0))
      endelse
    endif else begin
      if keyword_set(cubic) then return, interpolate(img, x, y, cubic=-0.5) else $
      if keyword_set(bilin) then return, interpolate(img, x, y) else $
                                 return, img(round(x), round(y))
    endelse
  
  endelse
  
end
