- Timestamp:
- 07/06/06 16:10:25 (18 years ago)
- Location:
- trunk/SRC/Interpolation
- Files:
-
- 22 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/SRC/Interpolation/angle.pro
r121 r125 1 1 ;--------- 2 2 ;+ 3 ; @file_comments north stereographic polar projection 3 ; @file_comments 4 ; north stereographic polar projection 4 5 ; 5 6 ; @param plam {in}{required} 6 7 ; 7 ; @param pphi {in}{required} 8 ; @param pphi {in}{required} 8 9 ; 9 10 ; @keyword DOUBLE {default=0} use double precision (default is float) 10 11 ; 11 12 ; @returns 12 ; gsinu,gcosu : sinus and cosinus of the angle 13 ; gsinv,gcosv between north-south direction 13 ; gsinu,gcosu : sinus and cosinus of the angle 14 ; gsinv,gcosv between north-south direction 14 15 ; gsint,gcost and the j-direction of the mesh 15 16 ; 16 ; @restrictions to compute the lateral boundary conditions, we assume17 ; t hat:17 ; @restrictions 18 ; to compute the lateral boundary conditions, we assume that: 18 19 ; (1) the first line is similar to the second line 19 ; => gcosu[*, 0] = gcosu[*, 1] 20 ; => gsinu[*, 0] = gsinu[*, 1] 20 ; => gcosu[*, 0] = gcosu[*, 1] 21 ; => gsinu[*, 0] = gsinu[*, 1] 21 22 ; (2) the grid follows OPA x periodicity rule, first column is 22 23 ; equal to the next to last column … … 26 27 ; 27 28 ; @history 28 ; --------------29 29 ; Original : 96-07 (O. Marti) 30 30 ; 98-06 (G. Madec) 31 ; Feb 2005: IDL adaptation S. Masson 31 ; Feb 2005: IDL adaptation S. Masson 32 32 ; 33 33 ; @version $Id$ 34 34 ; 35 35 ;- 36 ;---------37 36 ; 38 37 FUNCTION fsnspp, plam, pphi, DOUBLE = double … … 47 46 a = 2. * tan( !pi/4. - !pi/180.*float(pphi)/2. ) 48 47 x = cos( !pi/180.*float(plam) ) * a 49 y = sin( !pi/180.*float(plam) ) * a 48 y = sin( !pi/180.*float(plam) ) * a 50 49 ENDELSE 51 50 RETURN, {x:x, y:y} … … 150 149 znpv01 = -1; free memory 151 150 IF keyword_set(double) THEN zmnpvt = 1.e-14 > zmnpvt $ 152 ELSE zmnpvt = 1.e-6 > zmnpvt 151 ELSE zmnpvt = 1.e-6 > zmnpvt 153 152 ; ... j-direction: f-point segment direction (u-point) 154 153 zxffu = znpf00.x - znpf01.x … … 157 156 znpf01 = -1; free memory 158 157 IF keyword_set(double) THEN zmnpfu = 1.e-14 > zmnpfu $ 159 ELSE zmnpfu = 1.e-6 > zmnpfu 158 ELSE zmnpfu = 1.e-6 > zmnpfu 160 159 ; ... i-direction: f-point segment direction (v-point) 161 160 zxffv = znpf00.x - znpf10.x 162 zyffv = znpf00.y - znpf10.y 161 zyffv = znpf00.y - znpf10.y 163 162 znpf00 = -1 & znpf10 = -1; free memory 164 163 zmnpfv = sqrt ( temporary(znnpv) * ( zxffv*zxffv + zyffv*zyffv ) ) 165 164 IF keyword_set(double) THEN zmnpfv = 1.e-14 > zmnpfv $ 166 ELSE zmnpfv = 1.e-6 > zmnpfv 165 ELSE zmnpfv = 1.e-6 > zmnpfv 167 166 ; ... cosinus and sinus using scalar and vectorial products 168 167 gsint = ( znpt.x*zyvvt - znpt.y*zxvvt ) / zmnpvt … … 193 192 ; ================================ 194 193 ; 195 gcost[*, 0] = gcost[*, 1] 196 gsint[*, 0] = gsint[*, 1] 197 gcosu[*, 0] = gcosu[*, 1] 198 gsinu[*, 0] = gsinu[*, 1] 194 gcost[*, 0] = gcost[*, 1] 195 gsint[*, 0] = gsint[*, 1] 196 gcosu[*, 0] = gcosu[*, 1] 197 gsinu[*, 0] = gsinu[*, 1] 199 198 gcosv[0, *] = gcosv[jpj-2, *] 200 199 gsinv[0, *] = gsinv[jpj-2, *] -
trunk/SRC/Interpolation/clickincell.pro
r121 r125 1 1 ;+ 2 ; @file_comments click on a map and find in which cell the click was 2 ; @file_comments 3 ; click on a map and find in which cell the click was 3 4 ; 4 5 ; @categories finding where is a point on a grid … … 9 10 ; points). 10 11 ; 11 ; @keyword /DRAWCELL to draw the cell in which we clicked12 ; @keyword DRAWCELL to draw the cell in which we clicked 12 13 ; 13 14 ; @keyword COLOR the color used to draw the cells (Clicking one more 14 15 ; time in the same cell will draw the cell with the white color) 15 16 ; 16 ; @keyword /ORIGINAL to get the position of the cell regarding the original17 ; @keyword ORIGINAL to get the position of the cell regarding the original 17 18 ; grid (with no key_shift, ixminmesh, iyminmesh...) 18 19 ; 19 ; @keyword /IJ see outpus20 ; @keyword IJ see outpus 20 21 ; 21 22 ; @keyword _EXTRA to pass extra keywords to inquad and plot (when /drawcell) … … 25 26 ; is in memory in the variable of the common. If /ij keyword is 26 27 ; activated give 2D array (2, n) which are the i,j position of the 27 ; n selected cells. 28 ; n selected cells. 28 29 ; 29 30 ; @uses common.pro 30 31 ; 31 ; @examples 32 ; @examples 32 33 ; 33 ; 34 ; IDL> res = clickincell() 34 35 ; Click with the left button to select a cell. Clicking one more 35 36 ; time in the same cell remove the cell from the selection. 36 ; Click on the right button to quit. 37 ; Click on the right button to quit. 37 38 ; 38 ; 39 ; 39 ; IDL> plt, findgen(jpi,jpj),/nodata,map=[90,0,0],/ortho 40 ; IDL> print, clickincell(/draw,color=150,/xy) 40 41 ; 41 42 ; @history … … 44 45 ; 45 46 ; @version $Id$ 46 ;47 47 ; 48 48 ;- … … 117 117 cellnum = [cellnum, cell] 118 118 selected = [selected, 1] 119 already = n_elements(selected)-1 119 already = n_elements(selected)-1 120 120 ENDIF ELSE selected[already] = 1-selected[already] 121 121 IF keyword_set(drawcell) THEN BEGIN … … 129 129 2: ; middle button 130 130 ELSE: 131 ENDCASE 131 ENDCASE 132 132 ; get mousse position on the reference map 133 133 outwhile: … … 136 136 ; 137 137 good = where(selected NE 0) 138 IF good[0] EQ -1 THEN RETURN, -1 138 IF good[0] EQ -1 THEN RETURN, -1 139 139 ; 140 140 cellnum = cellnum[good] … … 183 183 ENDIF 184 184 ; 185 ncell = n_elements(xx) 185 ncell = n_elements(xx) 186 186 IF keyword_set(ij) THEN $ 187 187 RETURN, [reform(xx, 1, ncell, /over) $ 188 , reform(yy, 1, ncell, /over)] 188 , reform(yy, 1, ncell, /over)] 189 189 ; 190 190 IF keyword_set(original) THEN RETURN, xx+jpiglo*yy $ 191 ELSE RETURN, xx+jpi*yy 192 END 191 ELSE RETURN, xx+jpi*yy 192 END -
trunk/SRC/Interpolation/compute_fromirr_bilinear_weigaddr.pro
r121 r125 1 1 ;+ 2 ; @file_comments compute the weight and address needed to interpolate data from 3 ; an "irregular 2D grid" (defined as a grid made of quadrilateral cells) 4 ; to any grid using the bilinear method 5 ; 2 ; @file_comments 3 ; compute the weight and address needed to interpolate data from 4 ; an "irregular 2D grid" (defined as a grid made of quadrilateral cells) 5 ; to any grid using the bilinear method 6 ; 6 7 ; @categories interpolation 7 8 ; 8 ; @param olonin {in}{required} longitudeof the input data 9 ; @param olat {in}{required} latitude of the input data 10 ; @param omsk {in}{required} land/se mask of the input data 11 ; @param alonin {in}{required} longitude of the output data 12 ; @param alat {in}{required} latitude of the output data 13 ; @param amsk {in}{required} land/sea mask of the output data 9 ; @param olonin {in}{required} longitudeof the input data 10 ; @param olat {in}{required} latitude of the input data 11 ; @param omsk {in}{required} land/se mask of the input data 12 ; @param alonin {in}{required} longitude of the output data 13 ; @param alat {in}{required} latitude of the output data 14 ; @param amsk {in}{required} land/sea mask of the output data 14 15 ; 15 16 ; @param weig {out} … … 21 22 ; 22 23 ; @restrictions 23 ; - the input grid must be an "irregular 2D grid", defined as a grid made 24 ; 24 ; - the input grid must be an "irregular 2D grid", defined as a grid made 25 ; of quadrilateral cells which corners positions are defined with olonin and olat 25 26 ; - We supposed the data are located on a sphere, with a periodicity along 26 ; 27 ; the longitude 27 28 ; - to perform the bilinear interpolation within quadrilateral cells, we 28 ; 29 ; 30 ; - if some corners of the cell are land points, their weight is set to 0 31 ; 29 ; first morph the cell into a square cell and then compute the bilinear 30 ; interpolation. 31 ; - if some corners of the cell are land points, their weight is set to 0 32 ; and the weight is redistributed on the remaining "water" corners 32 33 ; - points located out of the southern and northern boundaries or in cells 33 ; containing only land points are set the the same value as their closest neighbor l; 34 ; containing only land points are set the the same value as their closest neighbor l 35 ; 34 36 ; @history 35 ; June 2006: Sebastien Masson (smasson\@lodyc.jussieu.fr) 36 ; 37 ; June 2006: Sebastien Masson (smasson\@lodyc.jussieu.fr) 37 38 ; 38 39 ; @version $Id$ … … 40 41 ;- 41 42 ; 42 ;----------------------------------------------------------43 ;----------------------------------------------------------44 ;45 43 PRO compute_fromirr_bilinear_weigaddr, olonin, olat, omsk, alonin, alat, amsk, weig, addr 46 44 ; 47 compile_opt idl2, strictarrsubs 45 compile_opt idl2, strictarrsubs 48 46 ; 49 47 jpia = (size(alonin, /dimensions))[0] … … 55 53 ; longitude, between 0 and 360 56 54 alon = alonin MOD 360 57 out = where(alon LT 0) 55 out = where(alon LT 0) 58 56 IF out[0] NE -1 THEN alon[out] = alon[out]+360 59 57 olon = olonin MOD 360 60 out = where(olon LT 0) 58 out = where(olon LT 0) 61 59 IF out[0] NE -1 THEN olon[out] = olon[out]+360 62 60 ; 63 61 ; we work only on the water points 64 62 owater = where(omsk EQ 1) 65 nowater = n_elements(owater) 63 nowater = n_elements(owater) 66 64 awater = where(amsk EQ 1) 67 nawater = n_elements(awater) 65 nawater = n_elements(awater) 68 66 ; 69 67 ; define all cells that have corners located at olon, olat … … 87 85 ; list the cells that have at least 1 ocean point as corner 88 86 good = where(total(omsk[celladdr], 1) GT 0) 89 ; keep only those cells 87 ; keep only those cells 90 88 celladdr = celladdr[*, temporary(good)] 91 89 ; … … 110 108 yy = alat[awater[n]] 111 109 ; 1) we reduce the number of ocean cells for which we will try to know if 112 ; xx,yy is inside. 110 ; xx,yy is inside. 113 111 CASE 1 OF 114 112 ; if we are near the norh pole … … 119 117 END 120 118 ; if we are near the longitude periodicity area 121 xx LE delta OR xx GE (360-delta):BEGIN 119 xx LE delta OR xx GE (360-delta):BEGIN 122 120 lat1 = yy-delta 123 121 lat2 = yy+delta … … 157 155 IF ind NE -1 THEN BEGIN 158 156 ind = good[ind] 159 ; we keep its address 157 ; we keep its address 160 158 foraddr[n] = ind 161 159 ; now, we morph the quadrilateral ocean cell into the reference square (0 -> 1) … … 173 171 , xcell[2, ind], ycell[2, ind] $ 174 172 , xcell[3, ind], ycell[3, ind], xx, yy) 175 ENDELSE 173 ENDELSE 176 174 ; take care of rounding errors... 177 175 zero = where(abs(xy) LT 1e-4) -
trunk/SRC/Interpolation/compute_fromreg_bilinear_weigaddr.pro
r121 r125 1 1 ;+ 2 ; @file_comments compute the weight and address needed to interpolate data from a 3 ; "regular grid" to any grid using the bilinear method 4 ; 2 ; @file_comments 3 ; compute the weight and address needed to interpolate data from a 4 ; "regular grid" to any grid using the bilinear method 5 ; 5 6 ; @categories interpolation 6 7 ; 7 ; @param alonin {in}{required} longitudeof the input data 8 ; @param alatin {in}{required} latitude of the input data 9 ; @param olonin {in}{required} longitude of the output data 10 ; @param olat {in}{required} latitude of the output data 11 ; 12 ; @keyword /NONORTHERNLINE activate if you don't whant to take into8 ; @param alonin {in}{required} longitudeof the input data 9 ; @param alatin {in}{required} latitude of the input data 10 ; @param olonin {in}{required} longitude of the output data 11 ; @param olat {in}{required} latitude of the output data 12 ; 13 ; @keyword NONORTHERNLINE activate if you don't want to take into 13 14 ; account the northen line of the input data when perfoming the 14 ; @keyword /NOSOUTHERNLINE activate if you don't whant to take into15 ; @keyword NOSOUTHERNLINE activate if you don't want to take into 15 16 ; account the southern line of the input data when perfoming the 16 17 ; interpolation. … … 24 25 ; 25 26 ; @restrictions 26 ; - 27 ; 28 ; 29 ; - 30 ; 31 ; - 32 ; 33 ; 27 ; - the input grid must be a "regular grid", defined as a grid for which each 28 ; lontitudes lines have the same latitude and each latitudes columns have the 29 ; same longitude. 30 ; - We supposed the data are located on a sphere, with a periodicity along 31 ; the longitude. 32 ; - points located out of the southern and northern boundaries are interpolated 33 ; using a linear interpolation only along the longitudinal direction. 34 ; 34 35 ; @history 35 ; November 2005: Sebastien Masson (smasson\@lodyc.jussieu.fr) 36 ; 36 ; November 2005: Sebastien Masson (smasson\@lodyc.jussieu.fr) 37 ; 37 38 ; @version $Id$ 38 39 ; 39 40 ;- 40 ;41 ;----------------------------------------------------------42 ;----------------------------------------------------------43 41 ; 44 42 PRO compute_fromreg_bilinear_weigaddr, alonin, alatin, olonin, olat, weig, addr $ … … 61 59 IF maxalon-minalon GE 360. THEN stop 62 60 ; alon must be monotonically increasing 63 IF array_equal(sort(alon), lindgen(jpia)) NE 1 THEN BEGIN 61 IF array_equal(sort(alon), lindgen(jpia)) NE 1 THEN BEGIN 64 62 shiftx = -(where(alon EQ min(alon)))[0] 65 63 alon = shift(alon, shiftx) 66 64 IF array_equal(sort(alon), lindgen(jpia)) NE 1 THEN stop 67 65 ENDIF ELSE shiftx = 0 68 ; for longitude periodic bo ndary condition we add the fist69 ; column on the right side of the array and 66 ; for longitude periodic boundary condition we add the fist 67 ; column on the right side of the array and 70 68 alon = [alon, alon[0]+360.] 71 69 jpia = jpia+1L … … 76 74 IF array_equal(sort(alat), lindgen(jpja)) NE 1 THEN stop 77 75 ; 78 if keyword_set(nonorthernline) then BEGIN 76 if keyword_set(nonorthernline) then BEGIN 79 77 jpja = jpja - 1L 80 78 alat = alat[0: jpja-1L] 81 79 ENDIF 82 if keyword_set(nosouthernline) then BEGIN 80 if keyword_set(nosouthernline) then BEGIN 83 81 alat = alat[1: jpja-1L] 84 82 jpja = jpja - 1L … … 103 101 ; if the ocean point is out of the atm grid, we use closest neighbor 104 102 ; interpolation 105 ; 103 ; 106 104 ; for each T point of oce grid, we find in which armospheric cell it is 107 105 ; located. … … 113 111 ; for longitude, each ocean points must be located in atm cell. 114 112 IF (where(pos[0, *] EQ -1))[0] NE -1 THEN stop 115 ; no ocean point should be located westward of the left bo ndary of the116 ; atm cell in which it is supposed to be located 113 ; no ocean point should be located westward of the left boundary of the 114 ; atm cell in which it is supposed to be located 117 115 IF total(olon LT alon[pos[0, *]]) NE 0 THEN stop 118 ; no ocean point should be located eastward of the right bo ndary of the119 ; atm cell in which it is supposed to be located 116 ; no ocean point should be located eastward of the right boundary of the 117 ; atm cell in which it is supposed to be located 120 118 IF total(olon GT alon[pos[0, *]+1]) NE 0 THEN stop 121 119 ; … … 124 122 ; we change the coordinates of each ocean points to fit into a 125 123 ; rectangle defined by: 126 ; 124 ; 127 125 ; y2 *------------* 128 126 ; | | … … 143 141 IF max(indx) GT jpia-2 THEN stop ; checks... 144 142 IF max(indy) GT jpja-2 THEN stop ; checks... 145 ; x coordinates of the atm cell 143 ; x coordinates of the atm cell 146 144 x1 = alon[indx] 147 145 x2 = alon[indx+1] … … 149 147 divi = temporary(x2)-x1 150 148 glamnew = (olon-x1)/temporary(divi) 151 x1 = -1 ; free memory 152 olon = -1 ; free memory 153 ; y coordinates of the atm cell 149 x1 = -1 ; free memory 150 olon = -1 ; free memory 151 ; y coordinates of the atm cell 154 152 y1 = alat[indy] 155 153 y2 = alat[indy+1] ; … … 159 157 IF zero[0] NE -1 THEN divi[zero] = 1. 160 158 gphinew = (olat-y1)/temporary(divi) 161 y1 = -1 ; free memory 159 y1 = -1 ; free memory 162 160 ; checks... 163 161 IF min(glamnew) LT 0 THEN stop … … 166 164 ; weight and address array used for bilinear interpolation. 167 165 xaddr = lonarr(4, jpio*jpjo) 168 xaddr[0, *] = indx 166 xaddr[0, *] = indx 169 167 xaddr[1, *] = indx + 1L 170 168 xaddr[2, *] = indx + 1L 171 xaddr[3, *] = indx 172 ; 169 xaddr[3, *] = indx 170 ; 173 171 yaddr = lonarr(4, jpio*jpjo) 174 172 yaddr[0, *] = indy … … 181 179 weig[1, *] = glamnew * (1.-gphinew) 182 180 weig[2, *] = glamnew * gphinew 183 weig[3, *] = (1.-glamnew) * gphinew 181 weig[3, *] = (1.-glamnew) * gphinew 184 182 ; free memory 185 183 gphinew = -1 … … 190 188 ybad = olat[bad] 191 189 ; the ocean points that are not located into an atm cell should be 192 ; located northward of the northern boundary of the atm grid 193 ; or southward of the southern boundary of the atm grid 190 ; located northward of the northern boundary of the atm grid 191 ; or southward of the southern boundary of the atm grid 194 192 IF total(ybad GE min(alat) AND ybad LE max(alat)) GE 1 THEN stop 195 193 ; … … 223 221 IF revy EQ 1 THEN yaddr = jpja - 1L - temporary(yaddr) 224 222 ; ; 225 addr = temporary(yaddr)*jpia + temporary(xaddr) 223 addr = temporary(yaddr)*jpia + temporary(xaddr) 226 224 ; 227 225 return -
trunk/SRC/Interpolation/compute_fromreg_imoms3_weigaddr.pro
r118 r125 1 1 ;+ 2 2 ; 3 ; @file_comments compute the weight and address neede to interpolate data from a 4 ; "regular grid" to any grid using the imoms3 method 5 ; 3 ; @file_comments 4 ; compute the weight and address neede to interpolate data from a 5 ; "regular grid" to any grid using the imoms3 method 6 ; 6 7 ; @categories interpolation 7 8 ; 8 ; @param alonin {in}{required} longitude of the input data 9 ; @param alatin {in}{required} latitude of the input data10 ; @param olonin {in}{required} longitude of the output data 11 ; @param olat {in}{required} latitude of the output data 12 ; 13 ; @keyword /NONORTHERNLINE14 ; @keyword /NOSOUTHERNLINE15 ; activate if you don't w hant to take into account the northen/southern line9 ; @param alonin {in}{required} longitude of the input data 10 ; @param alatin {in}{required} latitude of the input data 11 ; @param olonin {in}{required} longitude of the output data 12 ; @param olat {in}{required} latitude of the output data 13 ; 14 ; @keyword NONORTHERNLINE 15 ; @keyword NOSOUTHERNLINE 16 ; activate if you don't want to take into account the northen/southern line 16 17 ; of the input data when perfoming the interpolation. 17 18 ; … … 24 25 ; 25 26 ; @restrictions 26 ; - 27 ; 28 ; 27 ; - the input grid must be a "regular/rectangular grid", defined as a grid for 28 ; which each lontitudes lines have the same latitude and each latitudes columns 29 ; have the same longitude. 29 30 ; - We supposed the data are located on a sphere, with a periodicity along 30 ; 31 ; the longitude. 31 32 ; - points located between the first/last 2 lines are interpolated 32 ; 33 ; 34 ; - 35 ; 36 ; 33 ; using a imoms3 interpolation along the longitudinal direction and linear 34 ; interpolation along the latitudinal direction 35 ; - points located out of the southern and northern boundaries are interpolated 36 ; using a imoms3 interpolation only along the longitudinal direction. 37 ; 37 38 ; @history 38 ; November 2005: Sebastien Masson (smasson\@lodyc.jussieu.fr) 39 ; November 2005: Sebastien Masson (smasson\@lodyc.jussieu.fr) 39 40 ; March 2006: works for rectangular grids 40 41 ; … … 49 50 , NONORTHERNLINE = nonorthernline, NOSOUTHERNLINE = nosouthernline 50 51 ; 51 compile_opt idl2, strictarrsubs 52 compile_opt idl2, strictarrsubs 52 53 ; 53 54 alon = alonin … … 65 66 IF maxalon-minalon GE 360. THEN stop 66 67 ; alon must be monotonically increasing 67 IF array_equal(sort(alon), lindgen(jpia)) NE 1 THEN BEGIN 68 IF array_equal(sort(alon), lindgen(jpia)) NE 1 THEN BEGIN 68 69 shiftx = -(where(alon EQ min(alon)))[0] 69 70 alon = shift(alon, shiftx) … … 89 90 IF total((step-step[0]) GE 1.e-6) NE 0 THEN noregy = 1 90 91 ; 91 if keyword_set(nonorthernline) then BEGIN 92 if keyword_set(nonorthernline) then BEGIN 92 93 jpja = jpja - 1L 93 94 alat = alat[0: jpja-1L] 94 95 ENDIF 95 if keyword_set(nosouthernline) then BEGIN 96 if keyword_set(nosouthernline) then BEGIN 96 97 alat = alat[1: jpja-1L] 97 98 jpja = jpja - 1L … … 123 124 indexlat = value_locate(alat, olat) 124 125 ; 125 ; for the ocean points located below the atm line 126 ; for the ocean points located below the atm line 126 127 ; jpja-2 and above the line 1 127 128 ; for those points we can always find 16 neighbors … … 131 132 ilon = indexlon[short] 132 133 ilat = indexlat[short] 133 ; 134 IF NOT keyword_set(noregy) THEN BEGIN 134 ; 135 IF NOT keyword_set(noregy) THEN BEGIN 135 136 delta = alat[ilat+1L]-alat[ilat] 136 137 IF max(abs(delta-delta[0])) GE 1.e-6 THEN stop … … 147 148 d2 = (alat[ilat+1L]-olat[short])/delta 148 149 IF min(d2, max = ma) LE 0 THEN stop 149 IF ma GT 1 THEN stop 150 IF ma GT 1 THEN stop 150 151 wy2 = imoms3(temporary(d2)) 151 152 d3 = (alat[ilat+2L]-olat[short])/delta 152 153 IF min(d3, max = ma) LE 1 THEN stop 153 IF ma GT 2 THEN stop 154 IF ma GT 2 THEN stop 154 155 wy3 = imoms3(temporary(d3)) 155 ENDIF ELSE BEGIN 156 ENDIF ELSE BEGIN 156 157 nele = n_elements(short) 157 158 wy0 = fltarr(nele) … … 169 170 wy3[i] = imoms3(2-newlat) 170 171 ENDFOR 171 ENDELSE 172 ENDELSE 172 173 ; 173 174 mi = min(wy0+wy1+wy2+wy3, max = ma) … … 175 176 IF abs(ma-1) GE 1.e-6 THEN stop 176 177 ; 177 IF NOT keyword_set(noregx) THEN BEGIN 178 IF NOT keyword_set(noregx) THEN BEGIN 178 179 delta = alon[ilon]-alon[ilon-1L] 179 180 IF max(abs(delta-delta[0])) GE 1.e-6 THEN stop … … 194 195 d3 = (alon[ilon+2L]-olon[short])/delta 195 196 IF min(d3, max = ma) LE 1 THEN stop 196 IF ma GT 2 THEN stop 197 IF ma GT 2 THEN stop 197 198 wx3 = imoms3(temporary(d3)) 198 ENDIF ELSE BEGIN 199 ENDIF ELSE BEGIN 199 200 nele = n_elements(short) 200 201 wx0 = fltarr(nele) … … 212 213 wx3[i] = imoms3(2-newlon) 213 214 ENDFOR 214 ENDELSE 215 ENDELSE 215 216 ; 216 217 mi = min(wx0+wx1+wx2+wx3, max = ma) … … 220 221 ; line 0 221 222 xaddr[0, short] = ilon - 1L 222 xaddr[1, short] = ilon 223 xaddr[1, short] = ilon 223 224 xaddr[2, short] = ilon + 1L 224 225 xaddr[3, short] = ilon + 2L … … 233 234 ; line 1 234 235 xaddr[4, short] = ilon - 1L 235 xaddr[5, short] = ilon 236 xaddr[5, short] = ilon 236 237 xaddr[6, short] = ilon + 1L 237 238 xaddr[7, short] = ilon + 2L 238 yaddr[4, short] = ilat 239 yaddr[5, short] = ilat 240 yaddr[6, short] = ilat 241 yaddr[7, short] = ilat 239 yaddr[4, short] = ilat 240 yaddr[5, short] = ilat 241 yaddr[6, short] = ilat 242 yaddr[7, short] = ilat 242 243 weig[4, short] = wx0 * wy1 243 244 weig[5, short] = wx1 * wy1 … … 246 247 ; line 2 247 248 xaddr[8, short] = ilon - 1L 248 xaddr[9, short] = ilon 249 xaddr[9, short] = ilon 249 250 xaddr[10, short] = ilon + 1L 250 251 xaddr[11, short] = ilon + 2L … … 259 260 ; line 3 260 261 xaddr[12, short] = ilon - 1L 261 xaddr[13, short] = ilon 262 xaddr[13, short] = ilon 262 263 xaddr[14, short] = ilon + 1L 263 264 xaddr[15, short] = ilon + 2L … … 275 276 IF abs(ma-1) GE 1.e-6 THEN stop 276 277 ; 277 ; for the ocean points located between the atm lines 278 ; for the ocean points located between the atm lines 278 279 ; jpja-2 and jpja-1 or between the atm lines 0 and 1 279 280 ; linear interpolation between line 1 and line 2 … … 285 286 ; 286 287 delta = alat[ilat+1L]-alat[ilat] 287 IF NOT keyword_set(noregy) THEN BEGIN 288 IF NOT keyword_set(noregy) THEN BEGIN 288 289 IF max(abs(delta-delta[0])) GE 1.e-6 THEN stop 289 delta = delta[0] 290 ENDIF 290 delta = delta[0] 291 ENDIF 291 292 ; 292 293 d1 = (alat[ilat ]-olat[short])/delta … … 296 297 d2 = (alat[ilat+1L]-olat[short])/delta 297 298 IF min(d2, max = ma) LE 0 THEN stop 298 IF ma GT 1 THEN stop 299 IF ma GT 1 THEN stop 299 300 wy2 = 1.- temporary(d2) 300 301 ; … … 303 304 IF abs(ma-1) GE 1.e-6 THEN stop 304 305 ; but imoms3 along the longitude 305 IF NOT keyword_set(noregx) THEN BEGIN 306 IF NOT keyword_set(noregx) THEN BEGIN 306 307 delta = alon[ilon]-alon[ilon-1L] 307 308 IF max(abs(delta-delta[0])) GE 1.e-6 THEN stop … … 322 323 d3 = (alon[ilon+2L]-olon[short])/delta 323 324 IF min(d3, max = ma) LE 1 THEN stop 324 IF ma GT 2 THEN stop 325 IF ma GT 2 THEN stop 325 326 wx3 = imoms3(temporary(d3)) 326 ENDIF ELSE BEGIN 327 ENDIF ELSE BEGIN 327 328 nele = n_elements(short) 328 329 wx0 = fltarr(nele) … … 340 341 wx3[i] = imoms3(2-newlon) 341 342 ENDFOR 342 ENDELSE 343 ENDELSE 343 344 ; 344 345 mi = min(wx0+wx1+wx2+wx3, max = ma) … … 347 348 ; line 1 348 349 xaddr[0, short] = ilon - 1L 349 xaddr[1, short] = ilon 350 xaddr[1, short] = ilon 350 351 xaddr[2, short] = ilon + 1L 351 352 xaddr[3, short] = ilon + 2L 352 yaddr[0, short] = ilat 353 yaddr[1, short] = ilat 354 yaddr[2, short] = ilat 355 yaddr[3, short] = ilat 353 yaddr[0, short] = ilat 354 yaddr[1, short] = ilat 355 yaddr[2, short] = ilat 356 yaddr[3, short] = ilat 356 357 weig[0, short] = wx0 * wy1 357 358 weig[1, short] = wx1 * wy1 … … 360 361 ; line 2 361 362 xaddr[4, short] = ilon - 1L 362 xaddr[5, short] = ilon 363 xaddr[5, short] = ilon 363 364 xaddr[6, short] = ilon + 1L 364 365 xaddr[7, short] = ilon + 2L … … 379 380 ; 380 381 ; for the ocean points located below the line 0 381 ; Interpolation only along the longitude 382 ; Interpolation only along the longitude 382 383 ; 383 384 short = where(indexlat EQ -1) … … 385 386 ilon = indexlon[short] 386 387 ; 387 IF NOT keyword_set(noregx) THEN BEGIN 388 IF NOT keyword_set(noregx) THEN BEGIN 388 389 delta = alon[ilon]-alon[ilon-1L] 389 390 IF max(abs(delta-delta[0])) GE 1.e-6 THEN stop … … 404 405 d3 = (alon[ilon+2L]-olon[short])/delta 405 406 IF min(d3, max = ma) LE 1 THEN stop 406 IF ma GT 2 THEN stop 407 IF ma GT 2 THEN stop 407 408 wx3 = imoms3(temporary(d3)) 408 ENDIF ELSE BEGIN 409 ENDIF ELSE BEGIN 409 410 nele = n_elements(short) 410 411 wx0 = fltarr(nele) … … 422 423 wx3[i] = imoms3(2-newlon) 423 424 ENDFOR 424 ENDELSE 425 ENDELSE 425 426 ; 426 427 mi = min(wx0+wx1+wx2+wx3, max = ma) … … 429 430 ; line 1 430 431 xaddr[0, short] = ilon - 1L 431 xaddr[1, short] = ilon 432 xaddr[1, short] = ilon 432 433 xaddr[2, short] = ilon + 1L 433 434 xaddr[3, short] = ilon + 2L 434 yaddr[0:3, short] = 0 435 yaddr[0:3, short] = 0 435 436 weig[0, short] = wx0 436 437 weig[1, short] = wx1 … … 444 445 ENDIF 445 446 ; 446 ; for the ocean points located above jpia-1 447 ; Interpolation only along the longitude 447 ; for the ocean points located above jpia-1 448 ; Interpolation only along the longitude 448 449 ; 449 450 short = where(indexlat EQ jpja-1L) … … 451 452 ilon = indexlon[short] 452 453 ; 453 IF NOT keyword_set(noregx) THEN BEGIN 454 IF NOT keyword_set(noregx) THEN BEGIN 454 455 delta = alon[ilon]-alon[ilon-1L] 455 456 IF max(abs(delta-delta[0])) GE 1.e-6 THEN stop … … 470 471 d3 = (alon[ilon+2L]-olon[short])/delta 471 472 IF min(d3, max = ma) LE 1 THEN stop 472 IF ma GT 2 THEN stop 473 IF ma GT 2 THEN stop 473 474 wx3 = imoms3(temporary(d3)) 474 ENDIF ELSE BEGIN 475 ENDIF ELSE BEGIN 475 476 nele = n_elements(short) 476 477 wx0 = fltarr(nele) … … 488 489 wx3[i] = imoms3(2-newlon) 489 490 ENDFOR 490 ENDELSE 491 ENDELSE 491 492 ; 492 493 mi = min(wx0+wx1+wx2+wx3, max = ma) … … 495 496 ; line 1 496 497 xaddr[0, short] = ilon-1L 497 xaddr[1, short] = ilon 498 xaddr[1, short] = ilon 498 499 xaddr[2, short] = ilon+1L 499 500 xaddr[3, short] = ilon+2L … … 531 532 IF revy EQ 1 THEN yaddr = jpja - 1L - temporary(yaddr) 532 533 ; ; 533 addr = temporary(yaddr)*jpia+temporary(xaddr) 534 addr = temporary(yaddr)*jpia+temporary(xaddr) 534 535 ; 535 536 RETURN -
trunk/SRC/Interpolation/cutpar.pro
r121 r125 1 1 ;+ 2 2 ; 3 ; @file_comments cut p parallelogram(s) into p*n^2 parallelograms 3 ; @file_comments 4 ; cut p parallelogram(s) into p*n^2 parallelograms 4 5 ; 5 6 ; @categories basic work 6 7 ; 7 8 ; @param x0 {in}{required} 8 ; @param y0 {in}{required} 9 ; @param y0 {in}{required} 9 10 ; @param x1 {in}{required} 10 ; @param y1 {in}{required} 11 ; @param y1 {in}{required} 11 12 ; @param x2 {in}{required} 12 ; @param y2 {in}{required} 13 ; @param y2 {in}{required} 13 14 ; @param x3 {in}{required} 14 ; @param y3 {in}{required} 15 ; @param y3 {in}{required} 15 16 ; 1d arrays of p elements, giving the edge positions. The 16 ; edges must be given as in plot to traw the parallelogram. (see17 ; edges must be given as in plot to draw the parallelogram. (see 17 18 ; example). 18 19 ; 19 20 ; @param n {in}{required} each parallelogram will be cutted in n^2 pieces 20 21 ; 21 ; @keyword /endpointssee outputs22 ; @keyword ENDPOINTS see outputs 22 23 ; 23 ; @keyword /onsphereto specify that the points are located on a24 ; @keyword ONSPHERE to specify that the points are located on a 24 25 ; sphere. In this case, x and y corresponds to longitude and 25 26 ; latitude in degrees. 26 27 ; 27 28 ; @returns 28 ; - default:3d array(2,n^2,p) giving the center position of each29 ; 30 ; - /endpoints:3d array(2,(n+1)^2,p) giving the edge positions31 ; 29 ; - default: a 3d array(2,n^2,p) giving the center position of each 30 ; piece of the parallelograms 31 ; - if /ENDPOINTS : a 3d array(2,(n+1)^2,p) giving the edge positions 32 ; of each piece of the parallelograms 32 33 ; 33 34 ; @uses cutsegment.pro 34 35 ; 35 ; @examples 36 ; @examples 36 37 ; 37 38 ; IDL> x0 = [2,6,2] … … 56 57 ; 57 58 ;- 58 FUNCTION cutpar, x0, y0, x1, y1, x2, y2, x3, y3, n, endpoints = endpoints, onsphere= onsphere59 FUNCTION cutpar, x0, y0, x1, y1, x2, y2, x3, y3, n, ENDPOINTS = endpoints, ONSPHERE = onsphere 59 60 ; 60 61 compile_opt idl2, strictarrsubs … … 66 67 ; THEN stop; print, 'NOT a parallelogram' 67 68 ; x0(npar) 68 npar = n_elements(x0) 69 npar = n_elements(x0) 69 70 ; firstborder(2,n+keyword_set(endpoints),npar) 70 71 firstborder = cutsegment(x0, y0, x1, y1, n $ -
trunk/SRC/Interpolation/cutsegment.pro
r121 r125 1 1 ;+ 2 2 ; 3 ; @file_comments cut p segments into p*n equal parts 3 ; @file_comments 4 ; cut p segments into p*n equal parts 4 5 ; 5 6 ; @categories basic work … … 13 14 ; @param n {in}{required} the number of pieces we want to cut each segment 14 15 ; 15 ; @keyword /endpointssee ouputs16 ; @keyword ENDPOINTS see ouputs 16 17 ; 17 ; @keyword /onsphereto specify that the points are located on a18 ; @keyword ONSPHERE to specify that the points are located on a 18 19 ; sphere. In this case, x and y corresponds to longitude and 19 20 ; latitude in degrees. 20 21 ; 21 22 ; @returns 22 ; 23 ; 24 ; if /endpoints, a 3d array (2,n+1,p) that gives the25 ; 23 ; - default: a 3d array (2,n,p) that gives the coordinates of the 24 ; middle of the cutted segments. 25 ; - if /ENDPOINTS, a 3d array (2,n+1,p) that gives the 26 ; coordinates of the endpoints of the cutted segments. 26 27 ; 27 ; @examples 28 ; @examples 28 29 ; 29 ; 30 ; 31 ; 32 ; 33 ; 34 ; 35 ; 36 ; 37 ; 38 ; 30 ; IDL> x0=[2,5] 31 ; IDL> y0=[5,1] 32 ; IDL> x1=[9,3] 33 ; IDL> y1=[1,8] 34 ; IDL> res=cutsegment(x0, y0, x1, y1, 10) 35 ; IDL> splot, [0,10], [0,10], xstyle = 1, ystyle = 1,/nodata 36 ; IDL> oplot, [x0[0], x1[0]], [y0[0], y1[0]] 37 ; IDL> oplot, [res[0,*,0]], [res[1,*,0]], color = 20, psym = 1, thick = 3 38 ; IDL> oplot, [x0[1], x1[1]], [y0[1], y1[1]] 39 ; IDL> oplot, [res[0,*,1]], [res[1,*,1]], color = 40, psym = 1, thick = 3 39 40 ; 40 41 ; @history … … 45 46 ; 46 47 ;- 47 FUNCTION cutsegment, x0, y0, x1, y1, n, endpoints = endpoints, onsphere= onsphere48 FUNCTION cutsegment, x0, y0, x1, y1, n, ENDPOINTS = endpoints, ONSPHERE = onsphere 48 49 ; 49 50 compile_opt idl2, strictarrsubs 50 51 ; 51 52 ; number of segment 52 nseg = n_elements(x0) 53 nseg = n_elements(x0) 53 54 ; number of point to find on each segment 54 n2find = n+keyword_set(endpoints) 55 n2find = n+keyword_set(endpoints) 55 56 ; 56 57 IF keyword_set(onsphere) THEN BEGIN -
trunk/SRC/Interpolation/extrapolate.pro
r118 r125 1 1 ;+ 2 ; @file_comments extrapolate data (zinput) where maskinput eq 0 by filling 2 ; @file_comments 3 ; extrapolate data (zinput) where maskinput eq 0 by filling 3 4 ; step by step the coastline points with the mean value of the 8 neighbourgs. 4 5 ; … … 20 21 FUNCTION extrapolate, zinput, maskinput, nb_iteration, x_periodic = x_periodic, MINVAL = minval, MAXVAL = maxval 21 22 ; 22 compile_opt idl2, strictarrsubs 23 compile_opt idl2, strictarrsubs 23 24 ; 24 25 ; check the number of iteration used in the extrapolation. … … 28 29 ny = (size(zinput))[2] 29 30 ; take care of the boundary conditions... 30 ; 31 ; 31 32 ; for the x direction, we put 2 additional columns at the left and 32 ; right side of the array. 33 ; right side of the array. 33 34 ; for the y direction, we put 2 additional lines at the bottom and 34 ; top side of the array. 35 ; top side of the array. 35 36 ; These changes allow us to use shift function without taking care of 36 37 ; the x and y periodicity. … … 54 55 ;--------------------------------------------------------------- 55 56 ;--------------------------------------------------------------- 56 ; extrapolation 57 ; extrapolation 57 58 ;--------------------------------------------------------------- 58 59 sqrtinv = 1./sqrt(2) 59 60 ; 60 61 cnt = 1 61 ; When we look for the coast line, we don't w hant to select the62 ; When we look for the coast line, we don't want to select the 62 63 ; borderlines of the array. -> we force the value of the mask for 63 64 ; those lines. … … 86 87 ; we compute the weighted number of sea neighbourgs. 87 88 ; those 4 neighbours have a weight of 1: 88 ; * 89 ; *+* 90 ; * 89 ; * 90 ; *+* 91 ; * 91 92 ; 92 93 ; those 4 neighbours have a weight of 1/sqrt(2): 93 94 ; 94 95 ; * * 95 ; + 96 ; + 96 97 ; * * 97 98 ; … … 117 118 +1./sqrt(2)*(z[nx2+1+coast]+z[nx2-1+coast] $ 118 119 +z[-nx2+1+coast]+z[-nx2-1+coast]) 119 ; 120 ; 120 121 IF n_elements(minval) NE 0 THEN zcoast = minval > temporary(zcoast) 121 122 IF n_elements(maxval) NE 0 THEN zcoast = temporary(zcoast) < maxval … … 132 133 ; 133 134 cnt = cnt + 1 134 ; When we look for the coast line, we don't w hant to select the135 ; When we look for the coast line, we don't want to select the 135 136 ; borderlines of the array. -> we force the value of the mask for 136 137 ; those lines. … … 146 147 ; we return the original size of the array 147 148 ;--------------------------------------------------------------- 148 149 ; 149 150 return, z[1:nx, 1:ny] 150 END 151 END 151 152 -
trunk/SRC/Interpolation/fromirr.pro
r121 r125 1 1 ;+ 2 2 ; 3 ; @file_comments interpolate data from an irregular 2D grid to any 2D grid. 4 ; Only 1 metod available = bilinear 5 ; 3 ; @file_comments 4 ; interpolate data from an irregular 2D grid to any 2D grid. 5 ; Only 1 method available = bilinear 6 ; 6 7 ; @categories interpolation 7 8 ; 8 ; 9 ; 10 ; 11 ; 12 ; 13 ; 14 ; 15 ; 9 ; @param method {in}{required} a string defining the interpolation method. must be 'bilinear' 10 ; @param datain {in}{required} a 2D array the input data to interpolate 11 ; @param lonin {in}{optional} a 2D array defining the longitude of the input data 12 ; @param latin {in}{optional} a 2D array defining the latitude of the input data. 13 ; @param mskin {in}{optional} a 2D array, the land-sea mask of the input data (1 on ocean, 0 on land) 14 ; @param lonout {in}{optional} 1D or 2D array defining the longitude of the output data. 15 ; @param latout {in}{optional} 1D or 2D array defining the latitude of the output data. 16 ; @param mskout {in}{required} a 2D array, the land-sea mask of the ouput data (1 on ocean, 0 on land) 16 17 ; 17 18 ; @keyword WEIG (see ADDR) … … 27 28 ; @returns 2D array the interpolated data 28 29 ; 29 ; @restrictions We supposed the data are located on a sphere, with a periodicity along 30 ; the longitude. 31 ; Note that the input data can contain the same cells several times 32 ; (like ORCA grid near the north pole boundary) 30 ; @restrictions 31 ; We supposed the data are located on a sphere, with a periodicity along 32 ; the longitude. 33 ; Note that the input data can contain the same cells several times 34 ; (like ORCA grid near the north pole boundary) 33 35 ; 34 36 ; @examples 35 ; 37 ; 36 38 ; IDL> tncep = fromirr('bilinear', topa, glamt, gphit, tmask[*,*,0], lonout, latout, mskout) 37 39 ; 38 ; or 40 ; or 39 41 ; 40 42 ; IDL> t1ncep = fromirr('bilinear', topa, glamt, gphit, tmask[*,*,0], lonout, latout, mskout $ … … 44 46 ; 45 47 ; @history 46 ; June 2006: Sebastien Masson (smasson\@lodyc.jussieu.fr) 47 ; 48 ; June 2006: Sebastien Masson (smasson\@lodyc.jussieu.fr) 49 ; 48 50 ; @version $Id$ 49 51 ; … … 55 57 , WEIG = weig, ADDR = addr 56 58 ; 57 compile_opt strictarr, strictarrsubs 59 compile_opt strictarr, strictarrsubs 58 60 ; 59 61 ;--------------- … … 75 77 CASE method OF 76 78 'bilinear':compute_fromirr_bilinear_weigaddr, alon, alat, mskin, olon, olat, mskout, weig, addr 77 ELSE:BEGIN 79 ELSE:BEGIN 78 80 print, ' unknown interpolation method... we stop' 79 81 stop -
trunk/SRC/Interpolation/fromreg.pro
r121 r125 1 1 ;+ 2 2 ; 3 ; @file_comments interpolate data from a "regular/rectangular grid" to any grid. 4 ; 2 metods availables: bilinear and imoms3 5 ; A "regular/rectangular grid" is defined as a grid for which each lontitudes lines have 3 ; @file_comments 4 ; interpolate data from a "regular/rectangular grid" to any grid. 5 ; 2 methods availables: bilinear and imoms3 6 ; A "regular/rectangular grid" is defined as a grid for which each lontitudes lines have 6 7 ; the same latitude and each latitudes columns have the same longitude. 7 ; 8 ; 8 9 ; @categories interpolation 9 10 ; 10 ; @param method {in}{required} a string defining the interpolation method. 11 ; @param method {in}{required} a string defining the interpolation method. 11 12 ; must be 'bilinear' or 'imoms3' 12 13 ; @param datain {in}{required} a 2D array the input data to interpolate … … 26 27 ; case, lonin, latin, lonout and latout are not necessary. 27 28 ; 28 ; @keyword /NONORTHERNLINE29 ; @keyword /NOSOUTHERNLINE30 ; activate if you don't w hant to take into account the northen/southern line29 ; @keyword NONORTHERNLINE 30 ; @keyword NOSOUTHERNLINE 31 ; activate if you don't want to take into account the northen/southern line 31 32 ; of the input data when perfoming the interpolation. 32 33 ; 33 34 ; @returns 2D array the interpolated data 34 35 ; 35 ; @restrictions We supposed the data are located on a sphere, with a 36 ; periodicity along the longitude. 36 ; @restrictions 37 ; We supposed the data are located on a sphere, with a periodicity along the 38 ; longitude. 37 39 ; 38 ; @examples 39 ; 40 ; IDL> topa = fromreg('bilinear', tncep, xncep, yncep, glamt, gphit) 40 ; @examples 41 41 ; 42 ; or42 ; IDL> topa = fromreg('bilinear', tncep, xncep, yncep, glamt, gphit) 43 43 ; 44 ; IDL> t1opa = fromreg('bilinear', t1ncep, xncep, yncep, glamt, gphit, WEIG = a, ADDR = b) 45 ; IDL> help, a, b 46 ; IDL> t2opa = fromreg('bilinear', t2ncep, xncep, WEIG = a, ADDR = b) 44 ; or 45 ; 46 ; IDL> t1opa = fromreg('bilinear', t1ncep, xncep, yncep, glamt, gphit, WEIG = a, ADDR = b) 47 ; IDL> help, a, b 48 ; IDL> t2opa = fromreg('bilinear', t2ncep, xncep, WEIG = a, ADDR = b) 47 49 ; 48 50 ; @history 49 ; November 2005: Sebastien Masson (smasson\@lodyc.jussieu.fr) 51 ; November 2005: Sebastien Masson (smasson\@lodyc.jussieu.fr) 50 52 ; 51 53 ; @version $Id$ … … 60 62 , NOSOUTHERNLINE = nosouthernline 61 63 ; 62 compile_opt idl2, strictarrsubs 64 compile_opt idl2, strictarrsubs 63 65 ; 64 66 ;--------------- … … 81 83 'bilinear':compute_fromreg_bilinear_weigaddr, alon, alat, olon, olat, weig, addr, NONORTHERNLINE = nonorthernline, NOSOUTHERNLINE = nosouthernline 82 84 'imoms3': compute_fromreg_imoms3_weigaddr, alon, alat, olon, olat, weig, addr, NONORTHERNLINE = nonorthernline, NOSOUTHERNLINE = nosouthernline 83 ELSE:BEGIN 85 ELSE:BEGIN 84 86 print, ' unknown interpolation method... we stop' 85 87 stop -
trunk/SRC/Interpolation/get_gridparams.pro
r121 r125 5 5 ; and make sure it is 1D or 2D arrays 6 6 ; 7 ; or 7 ; or 8 8 ; 2) given longitude and latitude arrays get their dimensions and make 9 9 ; sure they are 1D or 2D arrays … … 13 13 ; @examples 14 14 ; 15 ; 1) 15 ; 1) 16 16 ; IDL> get_gridparams, file, lonname, latname, lon, lat, jpi, jpj, n_dimensions 17 17 ; 18 18 ; or 19 19 ; 20 ; 2) 20 ; 2) 21 21 ; IDL> get_gridparams, lon, lat, jpi, jpj, n_dimensions 22 22 ; … … 47 47 ; and each latitudes should be the sae for all longitudes). 48 48 ; 49 ; @keyword /DOUBLE use double precision to perform the computation49 ; @keyword DOUBLE use double precision to perform the computation 50 50 ; 51 51 ; @examples -
trunk/SRC/Interpolation/imoms3.pro
r118 r125 1 1 ;+ 2 ; 3 ; 2 ; 3 ; 4 4 ; @param xin {in}{required} 5 5 ; … … 13 13 14 14 x = abs(xin) 15 y = fltarr(n_elements(x)) 15 y = fltarr(n_elements(x)) 16 16 17 17 test1 = where(x LT 1) -
trunk/SRC/Interpolation/inquad.pro
r121 r125 1 1 ;+ 2 ; @file_comments to find if an (x,y) point is in a quadrilateral (x1,x2,x3,x4) 2 ; @file_comments 3 ; to find if an (x,y) point is in a quadrilateral (x1,x2,x3,x4) 3 4 ; 4 5 ; @categories grid manipulation … … 6 7 ; @param x {in}{required} 7 8 ; @param y {in}{required} 8 ; the coordinates of the point we want to know where it is. 9 ; Must be a scalar if / onsphere activated else can be scalar or array.9 ; the coordinates of the point we want to know where it is. 10 ; Must be a scalar if /ONSPHERE activated else can be scalar or array. 10 11 ; 11 12 ; @param x1 {in}{required} … … 17 18 ; @param x4 {in}{required} 18 19 ; @param y4 {in}{required} 19 ; the coordinates of the quadrilateral given in the CLOCKWISE order. 20 ; the coordinates of the quadrilateral given in the CLOCKWISE order. 20 21 ; Scalar or array. 21 22 ; 22 ; @keyword /DOUBLE use double precision to perform the computation23 ; 24 ; @keyword /ONSPHERE to specify that the quadilateral are on a sphere and23 ; @keyword DOUBLE use double precision to perform the computation 24 ; 25 ; @keyword ONSPHERE to specify that the quadilateral are on a sphere and 25 26 ; that teir coordinates are longitude-latitude coordinates. In this 26 27 ; case, est-west periodicity, poles singularity and other pbs 27 28 ; related to longitude-latitude coordinates are managed 28 ; automatically. 29 ; automatically. 29 30 ; 30 31 ; @keyword ZOOMRADIUS {default=4} … … 32 33 ; zoomradius degree where we look for the the quadrilateral which 33 34 ; contains the (x,y) point) used for the satellite projection 34 ; when / onsphere is activated.35 ; 4 seems to be the minimum which can be used. 35 ; when /ONSPHERE is activated. 36 ; 4 seems to be the minimum which can be used. 36 37 ; Can be increase if the cell size is larger than 5 degrees. 37 ; 38 ; @keyword /NOPRINT to suppress the print messages.38 ; 39 ; @keyword NOPRINT to suppress the print messages. 39 40 ; 40 41 ; @keyword NEWCOORD … … 45 46 ; quadrilateral number j with (0 <= j <= n_elements(x0)-1) 46 47 ; 47 ; @restrictions I think degenerated quadrilateral (e.g. flat of 48 ; twisted) is not work. This has to be tested. 49 ; 50 ; @examples 48 ; @restrictions 49 ; I think degenerated quadrilateral (e.g. flat of twisted) is not work. 50 ; This has to be tested. 51 ; 52 ; @examples 51 53 ; 52 54 ; IDL> x = 1.*[1, 2, 6, 7, 3] … … 70 72 ; Sebastien Masson (smasson\@lodyc.jussieu.fr) 71 73 ; August 2003 72 ; Based on Convert_clic_ij.pro written by Gurvan Madec 74 ; Based on Convert_clic_ij.pro written by Gurvan Madec 73 75 ; 74 76 ; @version $Id$ … … 100 102 x3 = x3 MOD 360 101 103 x4 = x4 MOD 360 102 ; save !map 104 ; save !map 103 105 save = {map:!map, x:!x, y:!y, z:!z, p:!p} 104 ; do a satellite projection 106 ; do a satellite projection 105 107 IF NOT keyword_set(zoomradius) THEN zoomradius = 4 106 108 map_set, y[0], x[0], 0, /satellite, sat_p = [1+zoomradius*20/6371.229, 0, 0], /noerase, /iso, /noborder 107 109 ; use normal coordinates to reject cells which are out of the projection. 108 tmp = convert_coord(x, y, /DATA, /TO_NORMAL, DOUBLE = double) 109 tmp1 = convert_coord(x1, y1, /DATA, /TO_NORMAL, DOUBLE = double) 110 tmp2 = convert_coord(x2, y2, /DATA, /TO_NORMAL, DOUBLE = double) 111 tmp3 = convert_coord(x3, y3, /DATA, /TO_NORMAL, DOUBLE = double) 112 tmp4 = convert_coord(x4, y4, /DATA, /TO_NORMAL, DOUBLE = double) 110 tmp = convert_coord(x, y, /DATA, /TO_NORMAL, DOUBLE = double) 111 tmp1 = convert_coord(x1, y1, /DATA, /TO_NORMAL, DOUBLE = double) 112 tmp2 = convert_coord(x2, y2, /DATA, /TO_NORMAL, DOUBLE = double) 113 tmp3 = convert_coord(x3, y3, /DATA, /TO_NORMAL, DOUBLE = double) 114 tmp4 = convert_coord(x4, y4, /DATA, /TO_NORMAL, DOUBLE = double) 113 115 ; remove cell which have one corner with coordinates equal to NaN 114 116 test = finite(tmp1[0, *]+tmp1[1, *]+tmp2[0, *]+tmp2[1, *] $ … … 150 152 ; 151 153 tmp1 = -1 & tmp2 = -1 & tmp3 = -1 & tmp4 = -1 152 ; remove cells which are obviously bad 154 ; remove cells which are obviously bad 153 155 test = (x1 GT x AND x2 GT x AND x3 GT x AND x4 GT x) $ 154 156 OR (x1 LT x AND x2 LT x AND x3 LT x AND x4 LT x) $ … … 179 181 ENDIF 180 182 ; 181 nquad = n_elements(good2) 183 nquad = n_elements(good2) 182 184 x1 = x1[good2] 183 185 y1 = y1[good2] … … 196 198 ; *((x-x2)*(y3-y2) GT (x3-x2)*(y-y2)) $ 197 199 ; *((x-x3)*(y4-y3) GT (x4-x3)*(y-y3)) $ 198 ; *((x-x4)*(y1-y4) GE (x1-x4)*(y-y4)) 200 ; *((x-x4)*(y1-y4) GE (x1-x4)*(y-y4)) 199 201 ; 200 202 ; computation of test without any do loop for ntofind points (x,y) and … … 202 204 ; test dimensions are (ntofind, nquad) 203 205 ; column i of test corresponds to the intersection of point i with all 204 ; quadirlateral. 205 ; row j of test corresponds to all the points localized in cell j 206 ; quadirlateral. 207 ; row j of test corresponds to all the points localized in cell j 206 208 test = $ 207 209 ; (x-x1) … … 277 279 ENDIF 278 280 return, -1 279 END 281 END 280 282 n_elements(found) GT ntofind:BEGIN 281 283 IF NOT keyword_set(noprint) THEN print, 'The point is in more than one cell' 282 END 284 END 283 285 ELSE: 284 286 ENDCASE 285 287 ENDIF ELSE BEGIN 286 ; if ntofind GT 1, found must be sorted 288 ; if ntofind GT 1, found must be sorted 287 289 ; i position of found. this corresponds to one x,y point 288 290 forsort = found MOD ntofind -
trunk/SRC/Interpolation/inrecgrid.pro
r121 r125 1 1 ;+ 2 2 ; 3 ; @file_comments given - a list of points, (x,y) position 4 ; - the x and y limits of a rectangular grid 5 ; find in which cell is located each given point. 3 ; @file_comments 4 , given - a list of points, (x,y) position 5 ; - the x and y limits of a rectangular grid 6 ; find in which cell is located each given point. 6 7 ; 7 8 ; @categories no DO loop, use the wonderfull value_locate function! 8 9 ; 9 ; @param x1d {in}{required} a 1d array, the x position on the points 10 ; @param y1d {in}{required} a 1d array, the y position on the points 11 ; @param left {in}{required} a 1d, monotonically increasing array, 10 ; @param x1d {in}{required} 11 ; a 1d array, the x position on the points 12 ; 13 ; @param y1d {in}{required} 14 ; a 1d array, the y position on the points 15 ; 16 ; @param left {in}{required} 17 ; a 1d, monotonically increasing array, 12 18 ; the position of the "left" border of each cell. 13 ; @param bottom {in}{required} a 1d, monotonically increasing array, 19 ; 20 ; @param bottom {in}{required} 21 ; a 1d, monotonically increasing array, 14 22 ; the position of the "bottom" border of each cell. 15 23 ; 16 ; @keyword /output2d to get the output as a 2d array (2,n_elements(x1d)), 24 ; @keyword OUTPUT2D 25 ; to get the output as a 2d array (2,n_elements(x1d)), 17 26 ; with res[0,*] the x index accoring to the 1d array defined by 18 27 ; left and res[1,*] the y index accoring to the 1d array defined by 19 28 ; bottom. 20 29 ; 21 ; @keyword checkout=[rbgrid,ubgrid] specify the right and upper bondaries of 30 ; @keyword CHECKOUT 31 ; = [rbgrid,ubgrid] specify the right and upper boundaries of 22 32 ; the grid and check if some points are out. 23 33 ; 24 ; @returns the index on the cell accoring to the 2d array defined by25 ; left and bottom.34 ; @returns 35 ; the index on the cell accoring to the 2d array defined by left and bottom. 26 36 ; 27 ; @examples 37 ; @examples 28 38 ; 29 ; 30 ; 31 ; 32 ; 39 ; IDL> a=indgen(5) 40 ; IDL> b=indgen(7) 41 ; IDL> r=inrecgrid([0.25,3.25,2],[4.25,2.8,1.4],a,b) 42 ; IDL> print, r 33 43 ; 20 13 7 34 ; 35 ; 44 ; IDL> r=inrecgrid([0.25,3.25,2],[4.25,2.8,1.4],a,a+1,b,b+1,/output2d) 45 ; IDL> print, r 36 46 ; 0.00000 4.00000 37 47 ; 3.00000 2.00000 38 48 ; 2.00000 1.00000 39 ; 49 ; 40 50 ; @history 41 ; 42 ; 43 ; 51 ; S. Masson (smasson\@lodyc.jussieu.fr) 52 ; July 3rd, 2002 53 ; October 3rd, 2003: use value_locate 44 54 ; 45 55 ; @version $Id$ 46 56 ; 47 57 ;- 48 49 FUNCTION inrecgrid, x1d, y1d, left, bottom, output2d = output2d, checkout = checkout 58 FUNCTION inrecgrid, x1d, y1d, left, bottom, OUTPUT2D = output2d, CHECKOUT = checkout 50 59 ; 51 60 compile_opt idl2, strictarrsubs … … 71 80 out = where(xpos EQ -1 OR ypos EQ -1) 72 81 IF out[0] NE -1 THEN res[out] = -1 73 ; 82 ; 74 83 RETURN, res 75 84 -
trunk/SRC/Interpolation/ll_narcs_distances.pro
r121 r125 3 3 ; @file_comments 4 4 ; This function returns the longitude and latitude [lon, lat] of 5 ;a point a given arc distance (-pi <= Arc_Dist <= pi), and azimuth (Az), 6 ;from a specified location Lon0, lat0. 7 ; Same as LL_ARC_DISTANCE but for n points without do loop. 5 ; a point a given arc distance (-pi <= Arc_Dist <= pi), and azimuth (Az), 6 ; from a specified location Lon0, lat0. 7 ; Same as LL_ARC_DISTANCE but for n points without do loop. 8 ; 9 ; Formula from Map Projections - a working manual. USGS paper 10 ; 1395. Equations (5-5) and (5-6). 8 11 ; 9 12 ; @categories Mapping, geography 10 13 ; 11 ; @param Lon0 {in}{required} An array containing the longitude of the starting point. 12 ; Values are assumed to be in radians unless the keyword 13 ; DEGREES is set. 14 ; @param Lat0 {in}{required} An array containing the latitude of the starting point. 15 ; Values are assumed to be in radians unless the keyword 16 ; DEGREES is set. 17 ; @param Arc_Dist {in}{required} The arc distance from Lon_lat0. The value must be between 14 ; @param Lon0 {in}{required} 15 ; An array containing the longitude of the starting point. 16 ; Values are assumed to be in radians unless the keyword DEGREES is set. 17 ; 18 ; @param Lat0 {in}{required} 19 ; An array containing the latitude of the starting point. 20 ; Values are assumed to be in radians unless the keyword DEGREES is set. 21 ; 22 ; @param Arc_Dist {in}{required} 23 ; The arc distance from Lon_lat0. The value must be between 18 24 ; -!PI and +!PI. To express distances in arc units, divide 19 25 ; by the radius of the globe expressed in the original units. 20 26 ; For example, if the radius of the earth is 6371 km, divide 21 ; the distance in km by 6371 to obtain the arc distance. 22 ; @param Az {in}{required} The azimuth from Lon_lat0. The value is assumed to be in 23 ; radians unless the keyword DEGREES is set. 27 ; the distance in km by 6371 to obtain the arc distance. 24 28 ; 25 ; @keyword DEGREES Set this keyword to express all measurements and 26 ; results in degrees. 29 ; @param Az {in}{required} 30 ; The azimuth from Lon_lat0. The value is assumed to be in 31 ; radians unless the keyword DEGREES is set. 32 ; 33 ; @keyword DEGREES 34 ; Set this keyword to express all measurements and results in degrees. 27 35 ; 28 36 ; @returns 29 ; a (2, n) array containing the 30 ; longitude / latitude of the resultings points. Values are in radians 31 ; unless the keyword DEGREES is set. 37 ; a (2, n) array containing the longitude/latitude of the resultings points. 38 ; Values are in radians unless the keyword DEGREES is set. 32 39 ; 33 ; @file_comments 34 ;Formula from Map Projections - a working manual. USGS paper 35 ;1395. Equations (5-5) and (5-6). 36 ; 37 ; @examples 40 ; @examples 38 41 ; IDL> Lon_lat0 = [1.0, 2.0]; Initial point specified in radians 39 42 ; IDL> Arc_Dist = 2.0; Arc distance in radians … … 43 46 ; 2.91415 -0.622234 44 47 ; 45 ; IDL> lon0 = [-10, 20, 100]46 ; IDL> lat0 = [0, -10, 45]47 ; IDL> lon1 = [10, 60, 280]48 ; IDL> lat1 = [0, 10, 45]49 ; IDL> dist = map_npoints(lon0, lat0, lon1, lat1, azimuth = azi, /two_by_two)50 ; IDL> earthradius = 6378206.4d051 ; IDL> res = ll_narcs_distances(lon0, lat0, dist/earthradius, azi, /degrees)52 ; IDL> print, reform(res[0, *])48 ; IDL> lon0 = [-10, 20, 100] 49 ; IDL> lat0 = [0, -10, 45] 50 ; IDL> lon1 = [10, 60, 280] 51 ; IDL> lat1 = [0, 10, 45] 52 ; IDL> dist = map_npoints(lon0, lat0, lon1, lat1, azimuth = azi, /two_by_two) 53 ; IDL> earthradius = 6378206.4d0 54 ; IDL> res = ll_narcs_distances(lon0, lat0, dist/earthradius, azi, /degrees) 55 ; IDL> print, reform(res[0, *]) 53 56 ; 10.000000 60.000000 280.00000 54 ; IDL> print, reform(res[1, *])55 ; 1.1999280e-15 10.000000 45.00000057 ; IDL> print, reform(res[1, *]) 58 ; 1.1999280e-15 10.000000 45.000000 56 59 ; 57 60 ; @history … … 62 65 ; @version $Id$ 63 66 ; 64 ;-65 66 ;+67 ; @file_comments Return the [lon, lat] of the point a given arc distance68 ;(-pi <= arc_dist <= pi),69 ; and azimuth (az), from lon_lat0.70 67 ;- 71 68 ; … … 94 91 95 92 zero = where(arc_dist eq 0, count) 96 IF count NE 0 THEN BEGIN 93 IF count NE 0 THEN BEGIN 97 94 lam[zero] = lon0[zero] 98 95 phi[zero] = lat0[zero] 99 ENDIF 96 ENDIF 100 97 101 98 if keyword_set(degs) then return, transpose([[lam], [phi]]) / s $ … … 103 100 104 101 end 105 106 -
trunk/SRC/Interpolation/map_npoints.pro
r121 r125 1 ;+ 2 ; 3 ; @file_comments 4 ; Return the distance in meter between all np0 points P0 and all5 ; np1 points P1 on a sphere. If keyword /TWO_BY_TWO is given then6 ; returns the distances between number n of P0 points and number7 ; 8 ; 9 ; 1 ;+ 2 ; 3 ; @file_comments 4 ; Return the distance in meter between all np0 points P0 and all 5 ; np1 points P1 on a sphere. If keyword /TWO_BY_TWO is given then 6 ; returns the distances between number n of P0 points and number 7 ; n of P1 points (in that case, np0 and np1 must be equal). 8 ; Same as map_2points with the meter parameter but for n points 9 ; without do loop. 10 10 ; 11 11 ; @categories Maps 12 12 ; 13 13 ; @param Lon0 {in}{required} 14 ; @param Lat0 {in}{required} 15 ; np0 elements vector. longitudes and latitudes of np0 points P0 14 ; @param Lat0 {in}{required} 15 ; np0 elements vector. longitudes and latitudes of np0 points P0 16 16 ; 17 17 ; @param Lon1 {in}{required} 18 ; @param Lat1 {in}{required} 19 ; np1 elements vector. longitude and latitude of np1 points P1 18 ; @param Lat1 {in}{required} 19 ; np1 elements vector. longitude and latitude of np1 points P1 20 20 ; 21 ; @keyword AZIMUTH A named variable that will receive the azimuth of the great 22 ; circle connecting the two points, P0 to P1 23 ; @keyword /MIDDLE to get the longitude/latitude of the middle point betwen P0 and P1. 24 ; @keyword RADIANS if set, inputs and angular outputs are in radians, otherwise 25 ;degrees. 26 ; @keyword RADIUS {default=6378206.4d0} 27 ; If given, return the distance between the two points calculated using the 21 ; @keyword AZIMUTH 22 ; A named variable that will receive the azimuth of the great 23 ; circle connecting the two points, P0 to P1 24 ; 25 ; @keyword MIDDLE 26 ; to get the longitude/latitude of the middle point betwen P0 and P1. 27 ; 28 ; @keyword RADIANS 29 ; if set, inputs and angular outputs are in radians, otherwise degrees. 30 ; 31 ; @keyword RADIUS {default=6378206.4d0} 32 ; If given, return the distance between the two points calculated using the 28 33 ; given radius. 29 34 ; Default value is the Earth radius. 30 35 ; 31 ; @keyword TWO_BY_TWO If given,then Map_nPoints returns the distances between 32 ; number n of P0 points and number n of P1 points (in that case, 33 ; np0 and np1 must be equal). 36 ; @keyword TWO_BY_TWO 37 ; If given,then Map_nPoints returns the distances between number n of 38 ; P0 points and number n of P1 points 39 ; In that case, np0 and np1 must be equal. 34 40 ; 35 41 ; @returns 36 ; An (np0,np1) array giving the distance in meter between np0 37 ; points P0 and np1 points P1. Element (i,j) of the ouput is the 38 ; distance between element P0[i] and P1[j]. 39 ; If keyword /TWO_BY_TWO is given then Map_nPoints returns 40 ; an np-element vector giving the distance in meter between P0[i] 41 ; and P1[i] (in that case, we have np0 = np1 = np) 42 ; if /MIDDLE see this keyword. 42 ; An (np0,np1) array giving the distance in meter between np0 43 ; points P0 and np1 points P1. Element (i,j) of the ouput is the 44 ; distance between element P0[i] and P1[j]. 45 ; If keyword /TWO_BY_TWO is given then Map_nPoints returns 46 ; an np-element vector giving the distance in meter between P0[i] 47 ; and P1[i] (in that case, we have np0 = np1 = np) ; if /MIDDLE see this keyword. 43 48 ; 44 49 ; @examples 45 50 ; IDL> print, $ 46 ; map_npoints([-105.15,1],[40.02,1],[-0.07,100,50],[51.30,20,0])47 ; 7551369.35600334.848 ; 12864354.10921254.49 ; 14919237.5455558.851 ; IDL> map_npoints([-105.15,1],[40.02,1],[-0.07,100,50],[51.30,20,0]) 52 ; 7551369.3 5600334.8 53 ; 12864354. 10921254. 54 ; 14919237. 5455558.8 50 55 ; 51 56 ; IDL> lon0 = [-10, 20, 100] … … 53 58 ; IDL> lon1 = [10, 60, 280] 54 59 ; IDL> lat1 = [0, 10, 45] 55 ; IDL> dist = map_npoints(lon0, lat0, lon1, lat1, azimuth= azi)60 ; IDL> dist = map_npoints(lon0, lat0, lon1, lat1, AZIMUTH = azi) 56 61 ; IDL> help, dist, azi 57 ; DIST DOUBLE= Array[3, 3]58 ; AZI DOUBLE= Array[3, 3]62 ; DIST DOUBLE = Array[3, 3] 63 ; AZI DOUBLE = Array[3, 3] 59 64 ; IDL> print, dist[4*lindgen(3)], azi[4*lindgen(3)] 60 ; 2226414.0 4957944.510018863.61 ; 90.000000 64.4944504.9615627e-1562 ; IDL> dist = map_npoints(lon0, lat0, lon1, lat1, azimuth = azi, /two_by_two)65 ; 2226414.0 4957944.5 10018863. 66 ; 90.000000 64.494450 4.9615627e-15 67 ; IDL> dist = map_npoints(lon0, lat0, lon1, lat1, AZIMUTH = azi, /TWO_BY_TWO) 63 68 ; IDL> help, dist, azi 64 ; DIST DOUBLE= Array[3]65 ; AZI DOUBLE= Array[3]69 ; DIST DOUBLE = Array[3] 70 ; AZI DOUBLE = Array[3] 66 71 ; IDL> print, dist, azi 67 ; 2226414.0 4957944.510018863.68 ; 90.000000 64.4944504.9615627e-1572 ; 2226414.0 4957944.5 10018863. 73 ; 90.000000 64.494450 4.9615627e-15 69 74 ; IDL> print, map_2points(lon0[0], lat0[0], lon1[0], lat1[0]) 70 ; 20.00000090.00000071 ; IDL> print, map_npoints(lon0[0], lat0[0], lon1[0], lat1[0], azi=azi)/6378206.4d0 / !dtor, azi72 ; 73 ; 75 ; 20.000000 90.000000 76 ; IDL> print, map_npoints(lon0[0], lat0[0], lon1[0], lat1[0], AZIMUTH=azi)/6378206.4d0 / !dtor, azi 77 ; 20.000000 78 ; 90.000000 74 79 ; 75 80 ; IDL> lon0 = [-10, 20, 100] … … 77 82 ; IDL> lon1 = [10, 60, 280] 78 83 ; IDL> lat1 = [0, 10, 45] 79 ; IDL> mid = map_npoints(lon0, lat0, lon1, lat1, / middle, /two_by_two)84 ; IDL> mid = map_npoints(lon0, lat0, lon1, lat1, /MIDDLE, /TWO_BY_TWO) 80 85 ; IDL> print, reform(mid[0,*]), reform(mid[1,*]) 81 ; 0.0000000 40.000000190.0000082 ; 0.0000000 -1.5902773e-1590.00000086 ; 0.0000000 40.000000 190.00000 87 ; 0.0000000 -1.5902773e-15 90.000000 83 88 ; IDL> print, (map_2points(lon0[0], lat0[0], lon1[0], lat1[0], npath = 3))[*, 1] 84 ; 0.00000000.000000089 ; 0.0000000 0.0000000 85 90 ; IDL> print, (map_2points(lon0[1], lat0[1], lon1[1], lat1[1], npath = 3))[*, 1] 86 ; 40.000000-1.5902773e-1591 ; 40.000000 -1.5902773e-15 87 92 ; IDL> print, (map_2points(lon0[2], lat0[2], lon1[2], lat1[2], npath = 3))[*, 1] 88 ; 190.0000090.00000093 ; 190.00000 90.000000 89 94 ; 90 95 ; @history 91 ; 96 ; Based on the IDL function map_2points.pro,v 1.6 2001/01/15 92 97 ; Sebastien Masson (smasson\@lodyc.jussieu.fr) 93 ; 98 ; October 2003 94 99 ; 95 100 ; @version $Id$ 96 101 ; 97 102 ;- 98 Function Map_npoints, lon0, lat0, lon1, lat1, azimuth= azimuth $99 ,RADIANS = radians, RADIUS = radius, MIDDLE = middle, TWO_BY_TWO = two_by_two103 Function Map_npoints, lon0, lat0, lon1, lat1, AZIMUTH = azimuth $ 104 , RADIANS = radians, RADIUS = radius, MIDDLE = middle, TWO_BY_TWO = two_by_two 100 105 101 106 COMPILE_OPT idl2, strictarrsubs 102 107 103 104 108 IF (N_PARAMS() LT 4) THEN $ 109 MESSAGE, 'Incorrect number of arguments.' 105 110 106 np0 = n_elements(lon0)107 108 109 np1 = n_elements(lon1)110 111 112 113 111 np0 = n_elements(lon0) 112 IF n_elements(lat0) NE np0 THEN $ 113 MESSAGE, 'lon0 and lat0 must have the same number of elements' 114 np1 = n_elements(lon1) 115 IF n_elements(lat1) NE np1 THEN $ 116 MESSAGE, 'lon1 and lat1 must have the same number of elements' 117 if keyword_set(two_by_two) AND np0 NE np1 then $ 118 MESSAGE, 'When using two_by_two keyword, P0 and P1 must have the same number of elements' 114 119 115 116 117 118 120 mx = MAX(ABS([lat0[*], lat1[*]])) 121 pi2 = !dpi/2 122 IF (mx GT (KEYWORD_SET(radians) ? pi2 : 90)) THEN $ 123 MESSAGE, 'Value of Latitude is out of allowed range.' 119 124 120 125 k = KEYWORD_SET(radians) ? 1.0d0 : !dpi/180.0 121 126 ;Earth equatorial radius, meters, Clarke 1866 ellipsoid 122 r_sphere = n_elements(RADIUS) NE 0 ? RADIUS : 6378206.4d0127 r_sphere = n_elements(RADIUS) NE 0 ? RADIUS : 6378206.4d0 123 128 ; 124 125 126 127 129 coslt1 = cos(k*lat1[*]) 130 sinlt1 = sin(k*lat1[*]) 131 coslt0 = cos(k*lat0[*]) 132 sinlt0 = sin(k*lat0[*]) 128 133 ; 129 134 IF np0 EQ np1 AND np1 EQ 1 THEN two_by_two = 1 130 135 ; 131 if NOT keyword_set(two_by_two) THEN BEGIN132 133 134 135 136 ENDIF136 if NOT keyword_set(two_by_two) THEN BEGIN 137 coslt1 = replicate(1.0d0, np0)#temporary(coslt1) 138 sinlt1 = replicate(1.0d0, np0)#temporary(sinlt1) 139 coslt0 = temporary(coslt0)#replicate(1.0d0, np1) 140 sinlt0 = temporary(sinlt0)#replicate(1.0d0, np1) 141 ENDIF 137 142 ; 138 if keyword_set(two_by_two) THEN BEGIN139 140 141 ENDIF ELSE BEGIN142 143 144 ENDELSE143 if keyword_set(two_by_two) THEN BEGIN 144 cosl0l1 = cos(k*(lon1[*]-lon0[*])) 145 sinl0l1 = sin(k*(lon1[*]-lon0[*])) 146 ENDIF ELSE BEGIN 147 cosl0l1 = cos(k*(replicate(1.0d0, np0)#lon1[*]-lon0[*]#replicate(1.0d0, np1))) 148 sinl0l1 = sin(k*(replicate(1.0d0, np0)#lon1[*]-lon0[*]#replicate(1.0d0, np1))) 149 ENDELSE 145 150 146 151 cosc = sinlt0 * sinlt1 + coslt0 * coslt1 * cosl0l1 ;Cos of angle between pnts 147 152 ; Avoid roundoff problems by clamping cosine range to [-1,1]. 148 153 cosc = -1.0d0 > cosc < 1.0d0 149 154 ; 150 151 152 153 154 cosaz = (coslt0 * sinlt1 - sinlt0*coslt1*cosl0l1) / sinc155 156 IF bad[0] NE -1 THEN BEGIN157 158 159 160 161 155 if arg_present(azimuth) OR keyword_set(middle) then begin 156 sinc = sqrt(1.0d0 - cosc*cosc) 157 bad = where(abs(sinc) le 1.0e-7) 158 IF bad[0] NE -1 THEN sinc[bad] = 1 159 cosaz = (coslt0 * sinlt1 - sinlt0*coslt1*cosl0l1) / sinc 160 sinaz = sinl0l1*coslt1/sinc 161 IF bad[0] NE -1 THEN BEGIN 162 sinc[bad] = 0.0d0 163 sinaz[bad] = 0.0d0 164 cosaz[bad] = 1.0d0 165 ENDIF 166 ENDIF 162 167 ; 163 168 IF keyword_set(middle) then BEGIN 164 169 165 170 s0 = 0.5d0 * acos(cosc) 166 171 ; 167 coss = cos(s0) 168 sins = sin(s0) 169 ; 170 lats = asin(sinlt0 * coss + coslt0 * sins * cosaz) / k 171 lons = atan(sins * sinaz, coslt0 * coss - sinlt0 * sins * cosaz) / k 172 coss = cos(s0) 173 sins = sin(s0) 172 174 ; 173 if keyword_set(two_by_two) THEN BEGIN 174 return, transpose([[lon0[*] + lons], [lats]]) 175 ENDIF ELSE BEGIN 176 return, [ [[lon0[*]#replicate(1.0d0, np1) + lons]], [[lats]] ] 177 ENDELSE 175 lats = asin(sinlt0 * coss + coslt0 * sins * cosaz) / k 176 lons = atan(sins * sinaz, coslt0 * coss - sinlt0 * sins * cosaz) / k 178 177 ; 179 ENDIF 178 if keyword_set(two_by_two) THEN BEGIN 179 return, transpose([[lon0[*] + lons], [lats]]) 180 ENDIF ELSE BEGIN 181 return, [ [[lon0[*]#replicate(1.0d0, np1) + lons]], [[lats]] ] 182 ENDELSE 180 183 ; 181 if arg_present(azimuth) then begin 182 azimuth = atan(sinaz, cosaz) 183 IF k NE 1.0d0 THEN azimuth = temporary(azimuth) / k 184 ENDIF 184 ENDIF 185 ; 186 if arg_present(azimuth) then begin 187 azimuth = atan(sinaz, cosaz) 188 IF k NE 1.0d0 THEN azimuth = temporary(azimuth) / k 189 ENDIF 185 190 return, acos(cosc) * r_sphere 186 191 ; -
trunk/SRC/Interpolation/neighbor.pro
r121 r125 2 2 ; 3 3 ; @file_comments 4 ; find the closetest point of (P0) within a list of np1 points5 ; P1 Which can be on a sphere4 ; find the closetest point of (P0) within a list of np1 points 5 ; P1 Which can be on a sphere 6 6 ; 7 7 ; @categories Maps 8 8 ; 9 ; @param p0lon {in}{required} scalar. longitudes of point P0. 10 ; @param p0lat {in}{required} scalar. latitudes of point P0. 11 ; @param neighlon {in}{optional} 12 ; @param neighlat {in}{optional} 9 ; @param p0lon {in}{required} scalar. longitudes of point P0. 10 ; @param p0lat {in}{required} scalar. latitudes of point P0. 11 ; @param neighlon {in}{optional} 12 ; @param neighlat {in}{optional} 13 13 ; 14 ; @keyword RADIANS if set, inputs and angular outputs are in radians, otherwise 15 ;degrees. 16 ; @keyword DISTANCE dis, to get back the distances between P0 and the np1 17 ; points P1 in the variable dis. 18 ; @keyword /SPHERE to activate if points are located on a sphere. 14 ; @keyword RADIANS 15 ; if set, inputs and angular outputs are in radians, otherwise degrees. 16 ; 17 ; @keyword DISTANCE 18 ; dis, to get back the distances between P0 and the np1 points P1 in the 19 ; variable dis. 20 ; 21 ; @keyword SPHERE to activate if points are located on a sphere. 19 22 ; 20 23 ; @returns 21 ; 24 ; index giving the P1[index] point that is the closest point of (P0) 22 25 ; 23 26 ; @examples 24 ; 25 ; 27 ; IDL> print, neighbor(-105.15,40.02,[-0.07,100,50],[51.30,20,0], $ 28 ; IDL> distance=dis) 26 29 ; 0 27 ; 30 ; IDL> print, dis 28 31 ; 105.684 206.125 160.228 29 32 ; … … 44 47 IF n_elements(p0lat) NE 1 THEN MESSAGE, 'Sorry p0lat must be a scalar' 45 48 p0lat = p0lat[0] 46 nneig = n_elements(neighlon) 49 nneig = n_elements(neighlon) 47 50 IF n_elements(neighlat) NE nneig THEN $ 48 51 MESSAGE, 'neighlon and neighlat must have the same number of elements' … … 52 55 distance = Map_nPoints(p0lon, p0lat, neighlon, neighlat $ 53 56 , radius = radius, radians = radians) 54 ENDIF ELSE BEGIN 57 ENDIF ELSE BEGIN 55 58 distance = (neighlon-p0lon)^2+(neighlat-p0lat)^2 56 59 IF arg_present(distance) THEN distance = sqrt(distance) -
trunk/SRC/Interpolation/quadrilateral2square.pro
r121 r125 1 1 ;+ 2 2 ; 3 ; @file_comments warm (or map) an arbitrary quadrilateral onto a unit square 3 ; @file_comments 4 ; warm (or map) an arbitrary quadrilateral onto a unit square 4 5 ; according to the 4-point correspondences: 5 6 ; (x0,y0) -> (0,0) … … 35 36 ; 36 37 ; (2,n) array: the new coodinates (xout, yout) of the (xin,yin) 37 ; point(s) after mapping. 38 ; point(s) after mapping. 38 39 ; If xin is a scalar, then n is equal to the number of elements of 39 40 ; x0. If xin is an array , then n is equal to the number of 40 41 ; elements of xin. 41 42 ; 42 ; @restrictions I think degenerated quadrilateral (e.g. flat of 43 ; twisted) is not work. This has to be tested. 43 ; @restrictions 44 ; I think degenerated quadrilateral (e.g. flat of twisted) is not work. 45 ; This has to be tested. 44 46 ; 45 ; @examples 47 ; @examples 46 48 ; 47 49 ; IDL> splot,[0,5],[0,3],/nodata,xstyle=1,ystyle=1 … … 61 63 ; IEEE Computer Society Press, Los Alamitos, California 62 64 ; Chapter 3, see p 52-56 63 ; 65 ; 64 66 ; 65 67 ; @version $Id$ … … 109 111 ; 110 112 ; compute the adjoint matrix 111 ; 113 ; 112 114 IF keyword_set(double) THEN adj = dblarr(9, n_elements(x0)) $ 113 115 ELSE adj = fltarr(9, n_elements(x0)) … … 122 124 adj[7, *] = a[6, *]*a[1, *]-a[0, *]*a[7, *] 123 125 adj[8, *] = a[0, *]*a[4, *]-a[3, *]*a[1, *] 124 ; 126 ; 125 127 IF n_elements(xin) EQ 1 THEN BEGIN 126 xin = replicate(xin, n_elements(x0)) 127 yin = replicate(yin, n_elements(x0)) 128 xin = replicate(xin, n_elements(x0)) 129 yin = replicate(yin, n_elements(x0)) 128 130 ENDIF 129 131 ; -
trunk/SRC/Interpolation/spl_fstdrv.pro
r121 r125 4 4 ;+ 5 5 ; 6 ; @file_comments SPL_FSTDRV returns the values of the first derivative of 6 ; @file_comments 7 ; SPL_FSTDRV returns the values of the first derivative of 7 8 ; the interpolating function at the points X2i. it is a double 8 9 ; precision array. … … 14 15 ; in a way that interpolated value are also in ascending order 15 16 ; 16 ; @examples 17 ; @examples 17 18 ; IDL> y2 = spl_fstdrv(x, y, yscd, x2) 18 19 ; 19 ; @param x {in}{required} An n-element (at least 2) input vector that specifies the 20 ; tabulate points in ascending order. 20 ; @param x {in}{required} 21 ; An n-element (at least 2) input vector that specifies the 22 ; tabulate points in ascending order. 21 23 ; 22 ; @param y {in}{required} f(x) = y. An n-element input vector that specifies the values 23 ; of the tabulated function F(Xi) corresponding to Xi. 24 ; @param y {in}{required} 25 ; f(x) = y. An n-element input vector that specifies the values 26 ; of the tabulated function F(Xi) corresponding to Xi. 24 27 ; 25 ; @param yscd {in}{required} The output from SPL_INIT for the specified X and Y. 28 ; @param yscd {in}{required} 29 ; The output from SPL_INIT for the specified X and Y. 26 30 ; 27 ; @param x2 {in}{required} The input values for which the first derivative values are 28 ; desired. X can be scalar or an array of values. 31 ; @param x2 {in}{required} 32 ; The input values for which the first derivative values are desired. 33 ; X can be scalar or an array of values. 29 34 30 ; @returns 35 ; @returns 31 36 ; 32 ; y2: f'(x2) = y2. 37 ; y2: f'(x2) = y2. 33 38 ; 34 39 ; @history … … 50 55 ny = n_elements(y) 51 56 ; x must have at least 2 elements 52 IF nx LT 2 THEN stop 57 IF nx LT 2 THEN stop 53 58 ; y must have the same number of elements than x 54 59 IF nx NE ny THEN stop 55 ; define loc in a way that 60 ; define loc in a way that 56 61 ; if loc[i] eq -1 : x2[i] < x[0] 57 62 ; if loc[i] eq nx2-1: x2[i] >= x[nx-1] 58 63 ; else : x[loc[i]] <= x2[i] < x[loc[i]+1] 59 64 loc = value_locate(x, x2) 60 ; change loc in order to 65 ; change loc in order to 61 66 ; use x[0] and x[1] even if x2[i] < x[0] -> extrapolation 62 67 ; use x[nx-2] and x[nx-1] even if x2[i] >= x[nx-1] -> extrapolation 63 loc = 0 > temporary(loc) < (nx-2) 68 loc = 0 > temporary(loc) < (nx-2) 64 69 ; distance between to consecutive x 65 70 deltax = x[loc+1]-x[loc] … … 74 79 - 1.0d/6.0d * (3.0d*a*a - 1.0d) * deltax * yscd[loc] $ 75 80 + 1.0d/6.0d * (3.0d*b*b - 1.0d) * deltax * yscd[loc+1] 76 ; beware of the computation precision... 81 ; beware of the computation precision... 77 82 ; force near zero values to be exactly 0.0 78 83 zero = where(abs(yfrst) LT 1.e-10) -
trunk/SRC/Interpolation/spl_incr.pro
r121 r125 12 12 ; in a way that interpolated values are also monotonically increasing. 13 13 ; 14 ; @param x1 {in}{required} 15 ; An n-element (at least 2) input vector that specifies the tabulate points in 14 ; @param x1 {in}{required} 15 ; An n-element (at least 2) input vector that specifies the tabulate points in 16 16 ; a strict ascending order. 17 17 ; 18 ; @param y1 {in}{required} 18 ; @param y1 {in}{required} 19 19 ; f(x) = y. An n-element input vector that specifies the values 20 20 ; of the tabulated function F(Xi) corresponding to Xi. As f is … … 22 22 ; monotonically increasing. y can have equal consecutive values. 23 23 ; 24 ; @param x2 {in}{required} 24 ; @param x2 {in}{required} 25 25 ; The input values for which the interpolated values are 26 ; desired. Its values must be strictly monotonically increasing. 26 ; desired. Its values must be strictly monotonically increasing. 27 27 ; 28 28 ; @param der2 29 ; @param x 30 ; 31 ; @returns 29 ; @param x 30 ; 31 ; @returns 32 32 ; 33 33 ; y2: f(x2) = y2. Double precision array … … 37 37 ; values (amplitude smaller than 1.e-6)... 38 38 ; 39 ; @examples 39 ; @examples 40 40 ; 41 41 ; IDL> n = 100L 42 ; IDL> x = (dindgen(n))^2 42 ; IDL> x = (dindgen(n))^2 43 43 ; IDL> y = abs(randomn(0, n)) 44 44 ; IDL> y[n/2:n/2+1] = 0. … … 53 53 ; IDL> oplot, x2, y2, color = 100 54 54 ; IDL> c = y2[1:n2-1] - y2[0:n2-2] 55 ; IDL> print, min(c) LT 0 55 ; IDL> print, min(c) LT 0 56 56 ; IDL> print, min(c, max = ma), ma 57 57 ; IDL> splot,c,xstyle=1,ystyle=1, yrange=[-.01,.05], ysurx=.25, petit = [1, 2, 2], /noerase … … 87 87 88 88 ;+ 89 ; @param x1 {in}{required} 90 ; An n-element (at least 2) input vector that specifies the tabulate points in 89 ; @param x1 {in}{required} 90 ; An n-element (at least 2) input vector that specifies the tabulate points in 91 91 ; a strict ascending order. 92 92 ; 93 ; @param y1 {in}{required} 93 ; @param y1 {in}{required} 94 94 ; f(x) = y. An n-element input vector that specifies the values 95 95 ; of the tabulated function F(Xi) corresponding to Xi. As f is … … 97 97 ; monotonically increasing. y can have equal consecutive values. 98 98 ; 99 ; @param x2 {in}{required} 99 ; @param x2 {in}{required} 100 100 ; The input values for which the interpolated values are 101 ; desired. Its values must be strictly monotonically increasing. 101 ; desired. Its values must be strictly monotonically increasing. 102 102 ; 103 103 ; @param der2 104 ; @param x 104 ; @param x 105 105 ; 106 106 ;- … … 134 134 ; @keyword YPN_1 The first derivative of the interpolating function at the 135 135 ; point Xn-1. If YPN_1 is omitted, the second derivative at the 136 ; boundary is set to zero, resulting in a "natural spline." 136 ; boundary is set to zero, resulting in a "natural spline." 137 137 ;- 138 138 FUNCTION spl_incr, x, y, x2, YP0 = yp0, YPN_1 = ypn_1 … … 148 148 nx2 = n_elements(x2) 149 149 ; x must have at least 2 elements 150 IF nx LT 2 THEN stop 150 IF nx LT 2 THEN stop 151 151 ; y must have the same number of elements than x 152 152 IF nx NE ny THEN stop 153 153 ; x be monotonically increasing 154 IF min(x[1:nx-1]-x[0:nx-2]) LE 0 THEN stop 154 IF min(x[1:nx-1]-x[0:nx-2]) LE 0 THEN stop 155 155 ; x2 be monotonically increasing 156 156 IF N_ELEMENTS(X2) GE 2 THEN $ 157 IF min(x2[1:nx2-1]-x2[0:nx2-2]) LE 0 THEN stop 157 IF min(x2[1:nx2-1]-x2[0:nx2-2]) LE 0 THEN stop 158 158 ; y be monotonically increasing 159 IF min(y[1:ny-1]-y[0:ny-2]) LT 0 THEN stop 159 IF min(y[1:ny-1]-y[0:ny-2]) LT 0 THEN stop 160 160 ;--------------------------------- 161 161 ; first check: check if two consecutive values are equal … … 172 172 xinx2_1 = value_locate(x2, x[bad+1]) 173 173 ; 174 ; left side ... if there is x2 values smaller that x[bad[0]]. 174 ; left side ... if there is x2 values smaller that x[bad[0]]. 175 175 ; we force ypn_1 = 0.0d 176 176 IF xinx2[0] NE -1 THEN BEGIN … … 178 178 IF xinx2[0] NE 0 THEN stop 179 179 y2[0] = y[0] 180 ENDIF ELSE BEGIN 180 ENDIF ELSE BEGIN 181 181 y2[0:xinx2[0]] $ 182 182 = spl_incr(x[0:bad[0]], y[0:bad[0]], x2[0:xinx2[0]] $ 183 183 , yp0 = yp0, ypn_1 = 0.0d) 184 ENDELSE 185 ENDIF 184 ENDELSE 185 ENDIF 186 186 ; flat section 187 187 IF xinx2_1[0] NE -1 THEN $ … … 206 206 ENDFOR 207 207 ENDIF 208 ; right side ... if there is x2 values larger that x[bad[cntbad-1]+1]. 208 ; right side ... if there is x2 values larger that x[bad[cntbad-1]+1]. 209 209 ; we force yp0 = 0.0d 210 210 IF xinx2_1[cntbad-1] NE nx2-1 THEN $ … … 237 237 ; 238 238 ; we define the new values of the keyword ypn_1: 239 ; if the first derivative of the last value of x is negative 239 ; if the first derivative of the last value of x is negative 240 240 ; we define the new values of the keyword ypn_1 to 0.0d0 241 IF bad[cntbad-1] EQ nx-1 THEN BEGIN 241 IF bad[cntbad-1] EQ nx-1 THEN BEGIN 242 242 ypn_1new = 0.0d 243 243 ; we remove this case from the list … … 248 248 ; 249 249 ; we define the new values of the keyword yp0: 250 ; if the first derivative of the first value of x is negative 250 ; if the first derivative of the first value of x is negative 251 251 ; we define the new values of the keyword yp0 to 0.0 252 252 IF bad[0] EQ 0 THEN BEGIN … … 265 265 ; else: there is still cases with negative derivative ... 266 266 ; we will cut spl_incr in n spl_incr and specify yp0, ypn_1 267 ; for each of this n spl_incr 267 ; for each of this n spl_incr 268 268 ENDIF ELSE BEGIN 269 269 ; define xinx2: see help of value_locate … … 273 273 xinx2 = value_locate(x2, x[bad]) 274 274 y2 = dblarr(nx2) 275 ; left side ... if there is x2 values smaller that x[bad[0]]. 275 ; left side ... if there is x2 values smaller that x[bad[0]]. 276 276 ; we force ypn_1 = 0.0d 277 277 IF xinx2[0] NE -1 THEN $ … … 280 280 , yp0 = yp0new, ypn_1 = 0.0d) 281 281 ; middle pieces ... if cntbad gt 1 then we have to cut spl_incr in 282 ; more than 2 pieces -> we have middle pieces for which 282 ; more than 2 pieces -> we have middle pieces for which 283 283 ; we force yp0 = 0.0d and ypn_1 = 0.0d 284 284 IF cntbad GT 1 THEN BEGIN … … 295 295 ENDFOR 296 296 ENDIF 297 ; right side ... if there is x2 values larger that x[bad[cntbad-1]]. 297 ; right side ... if there is x2 values larger that x[bad[cntbad-1]]. 298 298 ; we force yp0 = 0.0d 299 299 IF xinx2[cntbad-1] NE nx2-1 THEN $ … … 302 302 , x2[xinx2[cntbad-1]+1:nx2-1] $ 303 303 , yp0 = 0.0d, ypn_1 = ypn_1new) 304 ENDELSE 304 ENDELSE 305 305 ; we return the checked and corrected value of yfrst 306 306 ; FOR i = 0, nx-1 DO BEGIN 307 307 ; same = where(abs(x2- x[i]) LT 1.e-10, cnt) 308 ; ; IF cnt NE 0 THEN y2[same] = y[i] 308 ; ; IF cnt NE 0 THEN y2[same] = y[i] 309 309 ; ENDFOR 310 310 RETURN, y2 … … 313 313 ; we can be in this part of the code only if: 314 314 ; (1) spl_incr is called by itself 315 ; (2) none are the first derivative in x are negative (because they have been 316 ; checked and corrected by the previous call to spl_incr, see above) 315 ; (2) none are the first derivative in x are negative (because they have been 316 ; checked and corrected by the previous call to spl_incr, see above) 317 317 ;--------------------------------- 318 318 ; third check: we have to make sure that the first derivative cannot … … 321 321 ; 322 322 ; first we compute the first derivative, next we correct the values 323 ; where we know that the first derivative can be negative. 323 ; where we know that the first derivative can be negative. 324 324 ; 325 325 y2 = spl_interp(x, y, yscd, x2, /double) … … 330 330 ; y''= 6a*X + 2b 331 331 ; if we take X = x[i+1]-x[i] then 332 ; d = y[i]; c = y'[i]; b = 0.5 * y''[i], 332 ; d = y[i]; c = y'[i]; b = 0.5 * y''[i], 333 333 ; a = 1/6 * (y''[i+1]-y''[i])/(x[i+1]-x[i]) 334 ; 334 ; 335 335 ; y'[i] and y'[i+1] are positive so y' can be negative 336 ; between x[i] and x[i+1] only if 336 ; between x[i] and x[i+1] only if 337 337 ; 1) a > 0 338 338 ; ==> y''[i+1] > y''[i] 339 ; 2) y' reach its minimum value between x[i] and x[i+1] 340 ; -> 0 < - b/(3a) < x[i+1]-x[i] 339 ; 2) y' reach its minimum value between x[i] and x[i+1] 340 ; -> 0 < - b/(3a) < x[i+1]-x[i] 341 341 ; ==> y''[i+1] > 0 > y''[i] 342 342 ; … … 412 412 ; in those cases, the first derivative has 2 zero between 413 413 ; x[bad[ib]] and x[bad[ib]+1]. We look for the minimum value of the 414 ; first derivative that correspond to the inflection point of y 414 ; first derivative that correspond to the inflection point of y 415 415 xinfl = -bbb[ib]/(3.0d*aaa[ib]) 416 416 ; we compute the y value for xinfl 417 417 yinfl = aaa[ib]*xinfl*xinfl*xinfl + bbb[ib]*xinfl*xinfl $ 418 418 + ccc[ib]*xinfl + ddd[ib] 419 ; 419 ; 420 420 CASE 1 OF 421 421 ; if y[xinfl] smaller than y[bad[ib]] then we conserve y2 until … … 450 450 , yifrst[bad[ib]+1] $ 451 451 , x2[xinx2_3+1:xinx2_2[ib]]) 452 ENDIF 452 ENDIF 453 453 END 454 454 ; if y[xinfl] bigger than y[bad[ib]+1] then we conserve y2 from … … 480 480 , yifrst[bad[ib]] $ 481 481 , x2[xinx2_1[ib]+1:xinx2_3]) 482 ENDIF 482 ENDIF 483 483 END 484 484 ELSE:BEGIN … … 496 496 , yifrst[bad[ib]] $ 497 497 , x2[xinx2_1[ib]+1:xinx2_3]) 498 499 ENDIF 498 499 ENDIF 500 500 IF xinx2_2[ib] GE xinx2_3+1 THEN BEGIN 501 501 y2[xinx2_3+1:xinx2_2[ib]] $ … … 504 504 , yifrst[bad[ib]+1] $ 505 505 , x2[xinx2_3+1:xinx2_2[ib]]) 506 ENDIF 506 ENDIF 507 507 END 508 508 ENDCASE 509 509 510 END 510 END 511 511 ENDCASE 512 512 ENDIF -
trunk/SRC/Interpolation/spl_keep_mean.pro
r121 r125 14 14 ; data equa to the original values) 15 15 ; 16 ; @param x {in}{required} An n-element (at least 2) input vector that specifies the 17 ; tabulate points in a strict ascending order. 16 ; @param x {in}{required} 17 ; An n-element (at least 2) input vector that specifies the tabulate points in 18 ; a strict ascending order. 18 19 ; 19 ; @param yin {in}{required} an array with one element less than x. y[i] represents the 20 ; mean value between x[i] and x[i+1]. if /GE0 is activated, y must 21 ; have positive values. 20 ; @param yin {in}{required} 21 ; an array with one element less than x. y[i] represents the 22 ; mean value between x[i] and x[i+1]. if /GE0 is activated, y must 23 ; have positive values. 22 24 ; 23 ; @param x2 {in}{required} The input values for which the interpolated values are 24 ; desired. Its values must be strictly monotonically increasing. 25 ; @param x2 {in}{required} 26 ; The input values for which the interpolated values are desired. 27 ; Its values must be strictly monotonically increasing. 25 28 ; 29 ; @keyword GE0 30 ; to force that y2 is always GE than 0. In that case, y must also be GE than 0. 26 31 ; 27 ; @keyword /GE0 to force that y2 is always GE than 0. In that case, y must 28 ; also be GE than 0. 32 ; @keyword YP0 33 ; The first derivative of the interpolating function at the 34 ; point X0. If YP0 is omitted, the second derivative at the 35 ; boundary is set to zero, resulting in a "natural spline." 29 36 ; 30 ; @keyword YP0 The first derivative of the interpolating function at the 31 ; point X0. If YP0 is omitted, the second derivative at the 32 ; boundary is set to zero, resulting in a "natural spline." 37 ; @keyword YPN_1 38 ; The first derivative of the interpolating function at the 39 ; point Xn-1. If YPN_1 is omitted, the second derivative at the 40 ; boundary is set to zero, resulting in a "natural spline." 33 41 ; 34 ; @keyword YPN_1 The first derivative of the interpolating function at the 35 ; point Xn-1. If YPN_1 is omitted, the second derivative at the 36 ; boundary is set to zero, resulting in a "natural spline." 37 ; 38 ; @returns 42 ; @returns 39 43 ; 40 44 ; y2: the meean value between two consecutive values of x2. This … … 43 47 ; @restrictions 44 48 ; It might be possible that y2 has very small negative values 45 ; (amplitude smaller than 1.e-6)... 49 ; (amplitude smaller than 1.e-6)... 46 50 ; 47 51 ; 48 ; @examples 52 ; @examples 49 53 ; 50 54 ; 12 monthly values of precipitations into daily values: … … 89 93 nx2 = n_elements(x2) 90 94 ; x must have at least 2 elements 91 IF nx LT 2 THEN stop 95 IF nx LT 2 THEN stop 92 96 ; x2 must have at least 2 elements 93 IF nx2 LT 2 THEN stop 97 IF nx2 LT 2 THEN stop 94 98 ; x be monotonically increasing 95 IF min(x[1:nx-1]-x[0:nx-2]) LE 0 THEN stop 99 IF min(x[1:nx-1]-x[0:nx-2]) LE 0 THEN stop 96 100 ; x2 be monotonically increasing 97 IF min(x2[1:nx2-1]-x2[0:nx2-2]) LE 0 THEN stop 101 IF min(x2[1:nx2-1]-x2[0:nx2-2]) LE 0 THEN stop 98 102 ; 99 103 ;--------------------------------- … … 130 134 ; yfrst = 0.0d > temporary(yfrst) 131 135 RETURN, yfrst 132 136 133 137 ;------------------------------------------------------------------ 134 138 ;------------------------------------------------------------------ -
trunk/SRC/Interpolation/square2quadrilateral.pro
r121 r125 1 1 ;+ 2 2 ; 3 ; @file_comments warm (or map) a unit square onto an arbitrary quadrilateral 3 ; @file_comments 4 ; warm (or map) a unit square onto an arbitrary quadrilateral 4 5 ; according to the 4-point correspondences: 5 6 ; (0,0) -> (x0,y0) … … 13 14 ; @categories image, grid manipulation 14 15 ; 15 ; 16 ; @param x0in {in}{required} the coordinates of the quadrilateral 17 ; (see above for correspondance with the unit square). Can be 18 ; scalar or array. (x0,y0), (x1,y1), (x2,y2) and (x3,y3) are 19 ; given in the anticlockwise order. 20 ; @param y0in {in}{required} the coordinates of the quadrilateral 21 ; (see above for correspondance with the unit square). Can be 22 ; scalar or array. (x0,y0), (x1,y1), (x2,y2) and (x3,y3) are 23 ; given in the anticlockwise order. 24 ; @param x1in {in}{required} the coordinates of the quadrilateral 25 ; (see above for correspondance with the unit square). Can be 26 ; scalar or array. (x0,y0), (x1,y1), (x2,y2) and (x3,y3) are 27 ; given in the anticlockwise order. 28 ; @param y1in {in}{required} the coordinates of the quadrilateral 29 ; (see above for correspondance with the unit square). Can be 30 ; scalar or array. (x0,y0), (x1,y1), (x2,y2) and (x3,y3) are 31 ; given in the anticlockwise order. 32 ; @param x2in {in}{required} the coordinates of the quadrilateral 33 ; (see above for correspondance with the unit square). Can be 34 ; scalar or array. (x0,y0), (x1,y1), (x2,y2) and (x3,y3) are 35 ; given in the anticlockwise order. 36 ; @param y2in {in}{required} the coordinates of the quadrilateral 37 ; (see above for correspondance with the unit square). Can be 38 ; scalar or array. (x0,y0), (x1,y1), (x2,y2) and (x3,y3) are 39 ; given in the anticlockwise order. 40 ; @param x3in {in}{required} the coordinates of the quadrilateral 41 ; (see above for correspondance with the unit square). Can be 42 ; scalar or array. (x0,y0), (x1,y1), (x2,y2) and (x3,y3) are 43 ; given in the anticlockwise order. 44 ; @param y3in {in}{required} the coordinates of the quadrilateral 45 ; (see above for correspondance with the unit square). Can be 46 ; scalar or array. (x0,y0), (x1,y1), (x2,y2) and (x3,y3) are 47 ; given in the anticlockwise order. 48 ; 49 ; @param xxin {in}{optional} the coordinates of the point(s) for which we want to do the 16 ; @param x0in {in}{required} the coordinates of the quadrilateral 17 ; (see above for correspondance with the unit square). Can be 18 ; scalar or array. (x0,y0), (x1,y1), (x2,y2) and (x3,y3) are 19 ; given in the anticlockwise order. 20 ; @param y0in {in}{required} the coordinates of the quadrilateral 21 ; (see above for correspondance with the unit square). Can be 22 ; scalar or array. (x0,y0), (x1,y1), (x2,y2) and (x3,y3) are 23 ; given in the anticlockwise order. 24 ; @param x1in {in}{required} the coordinates of the quadrilateral 25 ; (see above for correspondance with the unit square). Can be 26 ; scalar or array. (x0,y0), (x1,y1), (x2,y2) and (x3,y3) are 27 ; given in the anticlockwise order. 28 ; @param y1in {in}{required} the coordinates of the quadrilateral 29 ; (see above for correspondance with the unit square). Can be 30 ; scalar or array. (x0,y0), (x1,y1), (x2,y2) and (x3,y3) are 31 ; given in the anticlockwise order. 32 ; @param x2in {in}{required} the coordinates of the quadrilateral 33 ; (see above for correspondance with the unit square). Can be 34 ; scalar or array. (x0,y0), (x1,y1), (x2,y2) and (x3,y3) are 35 ; given in the anticlockwise order. 36 ; @param y2in {in}{required} the coordinates of the quadrilateral 37 ; (see above for correspondance with the unit square). Can be 38 ; scalar or array. (x0,y0), (x1,y1), (x2,y2) and (x3,y3) are 39 ; given in the anticlockwise order. 40 ; @param x3in {in}{required} the coordinates of the quadrilateral 41 ; (see above for correspondance with the unit square). Can be 42 ; scalar or array. (x0,y0), (x1,y1), (x2,y2) and (x3,y3) are 43 ; given in the anticlockwise order. 44 ; @param y3in {in}{required} the coordinates of the quadrilateral 45 ; (see above for correspondance with the unit square). Can be 46 ; scalar or array. (x0,y0), (x1,y1), (x2,y2) and (x3,y3) are 47 ; given in the anticlockwise order. 48 ; 49 ; @param xxin {in}{optional} the coordinates of the point(s) for which we want to do the 50 50 ; mapping. Can be scalar or array. 51 ; 51 ; @param yyin {in}{optional} the coordinates of the point(s) for which we want to do the 52 52 ; mapping. Can be scalar or array. 53 53 ; … … 55 55 ; 56 56 ; (2,n) array: the new coodinates (xout, yout) of the (xin,yin) 57 ; point(s) after mapping. 57 ; point(s) after mapping. 58 58 ; If xin is a scalar, then n is equal to the number of elements of 59 59 ; x0. If xin is an array , then n is equal to the number of 60 60 ; elements of xin. 61 61 ; If xin and yin are omited, square2quadrilateral returns the 62 ; matrix A which is used for the inverse transformation. 62 ; matrix A which is used for the inverse transformation. 63 63 ; 64 64 ; … … 66 66 ; twisted) is not work. This has to be tested. 67 67 ; 68 ; @examples 68 ; @examples 69 69 ; 70 70 ; IDL> splot,[0,5],[0,3],/nodata,xstyle=1,ystyle=1 … … 81 81 ; IEEE Computer Society Press, Los Alamitos, California 82 82 ; Chapter 3, see p 52-56 83 ; 83 ; 84 84 ; 85 85 ; @version $Id$ … … 127 127 ; 128 128 IF keyword_set(double) THEN a = dblarr(8, n_elements(x0)) $ 129 ELSE a = fltarr(8, n_elements(x0)) 129 ELSE a = fltarr(8, n_elements(x0)) 130 130 ; 131 131 delx3 = x0-x1+x2-x3 … … 161 161 yy2 = y2[projectivemap] 162 162 yy3 = y3[projectivemap] 163 ; 163 ; 164 164 delx1 = xx1-xx2 165 165 dely1 = yy1-yy2 … … 186 186 a[7, projectivemap] = a23 187 187 ENDIF 188 ; 188 ; 189 189 IF NOT arg_present(xxin) THEN return, a 190 190 ; 191 191 IF n_elements(xin) EQ 1 THEN BEGIN 192 xin = replicate(xin, n_elements(x0)) 193 yin = replicate(yin, n_elements(x0)) 192 xin = replicate(xin, n_elements(x0)) 193 yin = replicate(yin, n_elements(x0)) 194 194 ENDIF 195 195 ;
Note: See TracChangeset
for help on using the changeset viewer.