|
|
◆ grid_transform_grid_vol7d_init()
| subroutine grid_transform_class::grid_transform_grid_vol7d_init |
( |
type(grid_transform), intent(out) |
this, |
|
|
type(transform_def), intent(in) |
trans, |
|
|
type(griddim_def), intent(in) |
in, |
|
|
type(vol7d), intent(inout) |
v7d_out, |
|
|
real, dimension(:,:), intent(in), optional |
maskgrid, |
|
|
real, dimension(:), intent(in), optional |
maskbounds, |
|
|
procedure(basic_find_index), optional, pointer |
find_index, |
|
|
character(len=*), intent(in), optional |
categoryappend |
|
) |
| |
|
private |
Constructor for a grid_transform object, defining a particular grid-to-sparse points transformation.
It defines an object describing a transformation from a rectangular grid to a set of sparse points; the abstract type of transformation is described in the transformation object trans (type transform_def) which must have been properly initialised. The additional information required here is the description of the input grid in (type griddim_def), and, if required by the transformation type, the information about the target sparse points over which the transformation should take place:
- for 'inter' transformation, this is provided in the form of a vol7d object (v7d_out argument, input), which must have been initialized with the coordinates of desired sparse points
- for 'polyinter' transformation, no target point information has to be provided in input (it is calculated on the basis of input grid and trans object), and the coordinates of the target points (polygons' centroids) are returned in output in v7d_out argument
- for 'maskinter' transformation, this is a two dimensional real field (maskgrid argument), which, together with the maskbounds argument (optional with default), divides the input grid in a number of subareas according to the values of maskinter, and, in this case, v7d_out is an output argument which returns the coordinates of the target points (subareas' centroids)
- for 'metamorphosis' transformation, no target point information has to be provided in input (it is calculated on the basis of input grid and trans object), except for 'mask' subtype, for which the same information as for 'maskinter' transformation has to be provided; in all the cases, as for 'polyinter', the information about target points is returned in output in v7d_out argument.
The generated grid_transform object is specific to the grid and sparse point list provided or computed. The function c_e can be used in order to check whether the object has been successfully initialised, if the result is .FALSE., it should not be used further on.
- Parametri
-
| [out] | this | grid_transformation object |
| [in] | trans | transformation object |
| [in] | in | griddim object to transform |
| [in,out] | v7d_out | vol7d object with the coordinates of the sparse points to be used as transformation target (input or output depending on type of transformation) |
| [in] | maskgrid | 2D field to be used for defining subareas according to its values, it must have the same shape as the field to be interpolated (for transformation type 'maskinter' and 'metamorphosis:mask') |
| [in] | maskbounds | array of boundary values for defining subareas from the values of maskgrid, the number of subareas is SIZE(maskbounds) - 1, if not provided a default based on extreme values of maskgrid is used |
| [in] | categoryappend | append this suffix to log4fortran namespace category |
Definizione alla linea 2058 del file grid_transform_class.F90.
2058 ynmax = this%inny - nr 2059 DO iy = 1, this%outny 2060 DO ix = 1, this%outnx 2061 IF (this%inter_index_x(ix,iy) < xnmin .OR. & 2062 this%inter_index_x(ix,iy) > xnmax .OR. & 2063 this%inter_index_y(ix,iy) < ynmin .OR. & 2064 this%inter_index_y(ix,iy) > ynmax) THEN 2065 this%inter_index_x(ix,iy) = imiss 2066 this%inter_index_y(ix,iy) = imiss 2072 CALL l4f_category_log(this%category, l4f_debug, & 2073 'stencilinter: stencil size '//t2c(n*n)) 2074 CALL l4f_category_log(this%category, l4f_debug, & 2075 'stencilinter: stencil points '//t2c(count(this%stencil))) 2083 ELSE IF (this%trans%trans_type == 'maskinter') THEN 2085 IF (.NOT. PRESENT(maskgrid)) THEN 2086 CALL l4f_category_log(this%category,l4f_error, & 2087 'grid_transform_init maskgrid argument missing for maskinter transformation') 2088 CALL raise_fatal_error() 2091 CALL get_val(in, nx=this%innx, ny=this%inny) 2092 IF (this%innx /= SIZE(maskgrid,1) .OR. this%inny /= SIZE(maskgrid,2)) THEN 2093 CALL l4f_category_log(this%category,l4f_error, & 2094 'grid_transform_init mask non conformal with input field') 2095 CALL l4f_category_log(this%category,l4f_error, & 2096 'mask: '//t2c( SIZE(maskgrid,1))// 'x'//t2c( SIZE(maskgrid,2))// & 2097 ' input field:'//t2c(this%innx)// 'x'//t2c(this%inny)) 2098 CALL raise_fatal_error() 2101 ALLOCATE(this%inter_index_x(this%innx,this%inny), & 2102 this%inter_index_y(this%innx,this%inny)) 2103 this%inter_index_x(:,:) = imiss 2104 this%inter_index_y(:,:) = 1 2107 CALL gen_mask_class() 2115 DO iy = 1, this%inny 2116 DO ix = 1, this%innx 2117 IF (c_e(maskgrid(ix,iy))) THEN 2118 IF (maskgrid(ix,iy) <= lmaskbounds(nmaskarea+1)) THEN 2119 DO n = nmaskarea, 1, -1 2120 IF (maskgrid(ix,iy) > lmaskbounds(n)) THEN 2121 this%inter_index_x(ix,iy) = n 2131 this%outnx = nmaskarea 2133 CALL delete(v7d_out) 2134 CALL init(v7d_out, time_definition=time_definition) 2135 CALL vol7d_alloc(v7d_out, nana=nmaskarea) 2140 CALL init(v7d_out%ana(n), & 2141 lon=stat_average(pack(lin%dim%lon(:,:), & 2142 mask=(this%inter_index_x(:,:) == n))), & 2143 lat=stat_average(pack(lin%dim%lat(:,:), & 2144 mask=(this%inter_index_x(:,:) == n)))) 2150 ELSE IF (this%trans%trans_type == 'metamorphosis') THEN 2157 CALL get_val(in, nx=this%innx, ny=this%inny) 2159 ALLOCATE(this%point_index(this%innx,this%inny)) 2160 this%point_index(:,:) = imiss 2162 IF (this%trans%sub_type /= 'index') THEN 2163 CALL delete(v7d_out) 2164 CALL init(v7d_out, time_definition=time_definition) 2167 IF (this%trans%sub_type == 'all' ) THEN 2169 this%outnx = this%innx*this%inny 2171 CALL vol7d_alloc(v7d_out, nana=this%outnx) 2176 CALL init(v7d_out%ana((iy-1)*this%innx+ix), & 2177 lon=lin%dim%lon(ix,iy),lat=lin%dim%lat(ix,iy)) 2179 this%point_index(ix,iy) = n 2185 ELSE IF (this%trans%sub_type == 'coordbb' ) THEN 2190 DO iy = 1, this%inny 2191 DO ix = 1, this%innx 2193 IF (lin%dim%lon(ix,iy) > this%trans%rect_coo%ilon .AND. & 2194 lin%dim%lon(ix,iy) < this%trans%rect_coo%flon .AND. & 2195 lin%dim%lat(ix,iy) > this%trans%rect_coo%ilat .AND. & 2196 lin%dim%lat(ix,iy) < this%trans%rect_coo%flat) THEN 2197 this%outnx = this%outnx + 1 2198 this%point_index(ix,iy) = this%outnx 2203 IF (this%outnx <= 0) THEN 2204 CALL l4f_category_log(this%category,l4f_warn, & 2205 "metamorphosis:coordbb: no points inside bounding box "//& 2206 trim(to_char(this%trans%rect_coo%ilon))// ","// & 2207 trim(to_char(this%trans%rect_coo%flon))// ","// & 2208 trim(to_char(this%trans%rect_coo%ilat))// ","// & 2209 trim(to_char(this%trans%rect_coo%flat))) 2212 CALL vol7d_alloc(v7d_out, nana=this%outnx) 2216 DO iy = 1, this%inny 2217 DO ix = 1, this%innx 2218 IF (c_e(this%point_index(ix,iy))) THEN 2220 CALL init(v7d_out%ana(n), & 2221 lon=lin%dim%lon(ix,iy), lat=lin%dim%lat(ix,iy)) 2228 ELSE IF (this%trans%sub_type == 'poly' ) THEN 2241 DO iy = 1, this%inny 2242 DO ix = 1, this%innx 2243 point = georef_coord_new(x=lin%dim%lon(ix,iy), y=lin%dim%lat(ix,iy)) 2244 DO n = 1, this%trans%poly%arraysize 2245 IF (inside(point, this%trans%poly%array(n))) THEN 2249 this%outnx = this%outnx + 1 2251 this%point_index(ix,iy) = n 2260 IF (this%outnx <= 0) THEN 2261 CALL l4f_category_log(this%category,l4f_warn, & 2262 "metamorphosis:poly: no points inside polygons") 2265 CALL vol7d_alloc(v7d_out, nana=this%outnx) 2268 DO iy = 1, this%inny 2269 DO ix = 1, this%innx 2270 IF (c_e(this%point_index(ix,iy))) THEN 2272 CALL init(v7d_out%ana(n), & 2273 lon=lin%dim%lon(ix,iy), lat=lin%dim%lat(ix,iy)) 2280 ELSE IF (this%trans%sub_type == 'mask' ) THEN 2282 IF (.NOT. PRESENT(maskgrid)) THEN 2283 CALL l4f_category_log(this%category,l4f_error, & 2284 'grid_transform_init maskgrid argument missing for metamorphosis:mask transformation') 2289 IF (this%innx /= SIZE(maskgrid,1) .OR. this%inny /= SIZE(maskgrid,2)) THEN 2290 CALL l4f_category_log(this%category,l4f_error, & 2291 'grid_transform_init mask non conformal with input field') 2292 CALL l4f_category_log(this%category,l4f_error, & 2293 'mask: '//t2c( SIZE(maskgrid,1))// 'x'//t2c( SIZE(maskgrid,2))// & 2294 ' input field:'//t2c(this%innx)// 'x'//t2c(this%inny)) 2300 CALL gen_mask_class() 2312 DO iy = 1, this%inny 2313 DO ix = 1, this%innx 2314 IF (c_e(maskgrid(ix,iy))) THEN 2315 IF (maskgrid(ix,iy) <= lmaskbounds(nmaskarea+1)) THEN 2316 DO n = nmaskarea, 1, -1 2317 IF (maskgrid(ix,iy) > lmaskbounds(n)) THEN 2321 this%outnx = this%outnx + 1 2323 this%point_index(ix,iy) = n 2334 IF (this%outnx <= 0) THEN 2335 CALL l4f_category_log(this%category,l4f_warn, & 2336 "grid_transform_init no points inside mask for metamorphosis:mask transformation") 2340 CALL l4f_category_log(this%category,l4f_info, & 2341 "points in subarea "//t2c(n)// ": "// & 2342 t2c(count(this%point_index(:,:) == n))) 2345 CALL vol7d_alloc(v7d_out, nana=this%outnx) 2348 DO iy = 1, this%inny 2349 DO ix = 1, this%innx 2350 IF (c_e(this%point_index(ix,iy))) THEN 2352 CALL init(v7d_out%ana(n),lon=lin%dim%lon(ix,iy),lat=lin%dim%lat(ix,iy)) 2359 ELSE IF (this%trans%sub_type == 'index') THEN 2360 this%outnx = SIZE(v7d_out%ana) 2365 IF (any(c_e(lin%dim%lon))) THEN 2366 DO n = 1, SIZE(v7d_out%ana) 2367 iy = (v7d_out%volanai(n,1,1) - 1)/this%innx + 1 2368 ix = v7d_out%volanai(n,1,1) - (iy-1)*this%innx 2369 this%point_index(ix,iy) = v7d_out%volanai(n,1,1) 2370 CALL init(v7d_out%ana(n), & 2371 lon=lin%dim%lon(ix,iy), lat=lin%dim%lat(ix,iy)) 2374 DO n = 1, SIZE(v7d_out%ana) 2375 iy = (v7d_out%volanai(n,1,1) - 1)/this%innx + 1 2376 ix = v7d_out%volanai(n,1,1) - (iy-1)*this%innx 2377 this%point_index(ix,iy) = v7d_out%volanai(n,1,1) 2387 SUBROUTINE gen_mask_class() 2388 REAL :: startmaskclass, mmin, mmax 2391 IF ( PRESENT(maskbounds)) THEN 2392 nmaskarea = SIZE(maskbounds) - 1 2393 IF (nmaskarea > 0) THEN 2394 lmaskbounds = maskbounds 2396 ELSE IF (nmaskarea == 0) THEN 2397 CALL l4f_category_log(this%category,l4f_warn, & 2398 'only one value provided for maskbounds, '//t2c(maskbounds(1)) & 2399 // ', it will be ignored') 2400 CALL l4f_category_log(this%category,l4f_warn, & 2401 'at least 2 values are required for maskbounds') 2405 mmin = minval(maskgrid, mask=c_e(maskgrid)) 2406 mmax = maxval(maskgrid, mask=c_e(maskgrid)) 2408 nmaskarea = int(mmax - mmin + 1.5) 2409 startmaskclass = mmin - 0.5 2411 ALLOCATE(lmaskbounds(nmaskarea+1)) 2412 lmaskbounds(:) = (/(startmaskclass+ REAL(i),i=0,nmaskarea)/) 2414 CALL l4f_category_log(this%category,l4f_debug, & 2415 'maskinter, '//t2c(nmaskarea)// ' subareas defined, with boundaries:') 2416 DO i = 1, SIZE(lmaskbounds) 2417 CALL l4f_category_log(this%category,l4f_debug, & 2418 'maskinter '//t2c(i)// ' '//t2c(lmaskbounds(i))) 2422 END SUBROUTINE gen_mask_class 2424 END SUBROUTINE grid_transform_grid_vol7d_init 2445 SUBROUTINE grid_transform_vol7d_grid_init(this, trans, v7d_in, out, categoryappend) 2446 TYPE(grid_transform), INTENT(out) :: this 2447 TYPE(transform_def), INTENT(in) :: trans 2448 TYPE(vol7d), INTENT(in) :: v7d_in 2449 TYPE(griddim_def), INTENT(in) :: out 2450 character(len=*), INTENT(in), OPTIONAL :: categoryappend 2453 DOUBLE PRECISION :: xmin, xmax, ymin, ymax, lonref 2454 DOUBLE PRECISION, ALLOCATABLE :: lon(:,:),lat(:,:) 2455 TYPE(griddim_def) :: lout 2458 CALL grid_transform_init_common(this, trans, categoryappend) 2460 CALL l4f_category_log(this%category, l4f_debug, "grid_transform v7d-vg6d") 2463 IF (this%trans%trans_type == 'inter') THEN 2465 IF ( this%trans%sub_type == 'linear' ) THEN 2467 this%innx= SIZE(v7d_in%ana) 2469 ALLOCATE(lon(this%innx,1),lat(this%innx,1)) 2470 ALLOCATE(this%inter_xp(this%innx,this%inny),this%inter_yp(this%innx,this%inny)) 2471 CALL getval(v7d_in%ana(:)%coord,lon=lon(:,1),lat=lat(:,1)) 2473 CALL copy (out, lout) 2475 lonref = 0.5d0*(maxval(lon(:,1), mask=c_e(lon(:,1))) + minval(lon(:,1), mask=c_e(lon(:,1)))) 2476 CALL griddim_set_central_lon(lout, lonref) 2478 CALL get_val(lout, nx=nx, ny=ny) 2481 ALLOCATE(this%inter_x(this%outnx,this%outny),this%inter_y(this%outnx,this%outny)) 2483 CALL get_val(lout, xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax) 2484 CALL proj(lout, lon, lat, this%inter_xp, this%inter_yp) 2485 CALL griddim_gen_coord(lout, this%inter_x, this%inter_y) 2494 ELSE IF (this%trans%trans_type == 'boxinter') THEN 2496 this%innx= SIZE(v7d_in%ana) 2499 ALLOCATE(lon(this%innx,1),lat(this%innx,1)) 2500 ALLOCATE(this%inter_index_x(this%innx,this%inny), & 2501 this%inter_index_y(this%innx,this%inny)) 2503 CALL getval(v7d_in%ana(:)%coord,lon=lon(:,1),lat=lat(:,1)) 2505 CALL copy (out, lout) 2507 lonref = 0.5d0*(maxval(lon(:,1), mask=c_e(lon(:,1))) + minval(lon(:,1), mask=c_e(lon(:,1)))) 2508 CALL griddim_set_central_lon(lout, lonref) 2510 CALL get_val(lout, nx=this%outnx, ny=this%outny, & 2511 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax) 2514 IF (.NOT.c_e(this%trans%area_info%boxdx)) & 2515 CALL get_val(out, dx=this%trans%area_info%boxdx) 2516 IF (.NOT.c_e(this%trans%area_info%boxdy)) & 2517 CALL get_val(out, dx=this%trans%area_info%boxdy) 2519 this%trans%area_info%boxdx = this%trans%area_info%boxdx*0.5d0 2520 this%trans%area_info%boxdy = this%trans%area_info%boxdy*0.5d0 2523 CALL this%find_index(lout, .true., & 2524 this%outnx, this%outny, xmin, xmax, ymin, ymax, & 2525 lon, lat, .false., & 2526 this%inter_index_x, this%inter_index_y) 2535 END SUBROUTINE grid_transform_vol7d_grid_init 2572 SUBROUTINE grid_transform_vol7d_vol7d_init(this, trans, v7d_in, v7d_out, & 2573 maskbounds, categoryappend) 2574 TYPE(grid_transform), INTENT(out) :: this 2575 TYPE(transform_def), INTENT(in) :: trans 2576 TYPE(vol7d), INTENT(in) :: v7d_in 2577 TYPE(vol7d), INTENT(inout) :: v7d_out 2578 REAL, INTENT(in), OPTIONAL :: maskbounds(:) 2579 CHARACTER(len=*), INTENT(in), OPTIONAL :: categoryappend 2582 DOUBLE PRECISION, ALLOCATABLE :: lon(:), lat(:) 2584 DOUBLE PRECISION :: lon1, lat1 2585 TYPE(georef_coord) :: point 2588 CALL grid_transform_init_common(this, trans, categoryappend) 2590 CALL l4f_category_log(this%category, l4f_debug, "grid_transform v7d-v7d") 2593 IF (this%trans%trans_type == 'inter') THEN 2595 IF ( this%trans%sub_type == 'linear' ) THEN 2597 CALL vol7d_alloc_vol(v7d_out) 2598 this%outnx= SIZE(v7d_out%ana) 2601 this%innx= SIZE(v7d_in%ana) 2604 ALLOCATE(this%inter_xp(this%innx,this%inny),this%inter_yp(this%innx,this%inny)) 2605 ALLOCATE(this%inter_x(this%outnx,this%outny),this%inter_y(this%outnx,this%outny)) 2607 CALL getval(v7d_in%ana(:)%coord,lon=this%inter_xp(:,1),lat=this%inter_yp(:,1)) 2608 CALL getval(v7d_out%ana(:)%coord,lon=this%inter_x(:,1),lat=this%inter_y(:,1)) 2614 ELSE IF (this%trans%trans_type == 'polyinter') THEN
|