|
|
◆ grid_transform_init()
| subroutine grid_transform_class::grid_transform_init |
( |
type(grid_transform), intent(out) |
this, |
|
|
type(transform_def), intent(in) |
trans, |
|
|
type(griddim_def), intent(inout) |
in, |
|
|
type(griddim_def), intent(inout) |
out, |
|
|
real, dimension(:,:), intent(in), optional |
maskgrid, |
|
|
real, dimension(:), intent(in), optional |
maskbounds, |
|
|
character(len=*), intent(in), optional |
categoryappend |
|
) |
| |
|
private |
Constructor for a grid_transform object, defining a particular grid-to-grid transformation.
It defines an object describing a transformation from one rectangular grid to another; 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), the description of the output grid out (type griddim_def as well). The description of the output grid must be initialized for interpolating type transformations ('inter' and 'boxinter'), while it is generated by this constructor and returned in output for 'zoom', 'boxregrid', 'maskgen' and 'polyinter' transformations.
The generated grid_transform object is specific to the input and output grids involved. 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,out] | in | griddim object to transform |
| [in,out] | out | griddim object defining target grid (input or output depending on type of transformation) |
| [in] | maskgrid | 2D field to be used for defining valid points, it must have the same shape as the field to be interpolated (for transformation type 'metamorphosis:maskvalid') |
| [in] | maskbounds | array of boundary values for defining a subset of valid points where the values of maskgrid are within the first and last value of maskbounds (for transformation type 'metamorphosis:maskvalid/settoinvalid' and others) |
| [in] | categoryappend | append this suffix to log4fortran namespace category |
Definizione alla linea 1430 del file grid_transform_class.F90.
1431 CALL proj(in, lout%dim%lon, lout%dim%lat, this%inter_xp, this%inter_yp) 1434 CALL this%find_index(in, .true., & 1435 this%innx, this%inny, xmin, xmax, ymin, ymax, & 1436 lout%dim%lon, lout%dim%lat, this%trans%extrap, & 1437 this%inter_index_x, this%inter_index_y) 1439 IF (this%trans%trans_type == 'intersearch') THEN 1440 ALLOCATE(this%inter_x(this%innx,this%inny), & 1441 this%inter_y(this%innx,this%inny)) 1442 ALLOCATE(this%inter_xp(this%outnx,this%outny), & 1443 this%inter_yp(this%outnx,this%outny)) 1446 CALL griddim_gen_coord(in, this%inter_x, this%inter_y) 1448 CALL proj(in, lout%dim%lon, lout%dim%lat, this%inter_xp, this%inter_yp) 1456 ELSE IF (this%trans%trans_type == 'boxinter') THEN 1458 CALL outgrid_setup() 1459 CALL get_val(in, nx=this%innx, ny=this%inny) 1460 CALL get_val(out, nx=this%outnx, ny=this%outny, & 1461 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax) 1464 IF (.NOT.c_e(this%trans%area_info%boxdx)) & 1465 CALL get_val(out, dx=this%trans%area_info%boxdx) 1466 IF (.NOT.c_e(this%trans%area_info%boxdy)) & 1467 CALL get_val(out, dx=this%trans%area_info%boxdy) 1469 this%trans%area_info%boxdx = this%trans%area_info%boxdx*0.5d0 1470 this%trans%area_info%boxdy = this%trans%area_info%boxdy*0.5d0 1472 ALLOCATE(this%inter_index_x(this%innx,this%inny), & 1473 this%inter_index_y(this%innx,this%inny)) 1479 CALL this%find_index(out, .true., & 1480 this%outnx, this%outny, xmin, xmax, ymin, ymax, & 1481 lin%dim%lon, lin%dim%lat, .false., & 1482 this%inter_index_x, this%inter_index_y) 1487 ELSE IF (this%trans%trans_type == 'stencilinter') THEN 1489 CALL outgrid_setup() 1491 CALL get_val(in, nx=this%innx, ny=this%inny, & 1492 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax) 1493 CALL get_val(out, nx=this%outnx, ny=this%outny) 1495 ALLOCATE (this%inter_index_x(this%outnx,this%outny), & 1496 this%inter_index_y(this%outnx,this%outny)) 1497 CALL copy(out, lout) 1499 CALL this%find_index(in, .true., & 1500 this%innx, this%inny, xmin, xmax, ymin, ymax, & 1501 lout%dim%lon, lout%dim%lat, this%trans%extrap, & 1502 this%inter_index_x, this%inter_index_y) 1505 nr = int(this%trans%area_info%radius) 1508 r2 = this%trans%area_info%radius**2 1509 ALLOCATE(this%stencil(n,n)) 1510 this%stencil(:,:) = .true. 1513 IF ((ix-nm)**2+(iy-nm)**2 > r2) this%stencil(ix,iy) = .false. 1520 xnmax = this%innx - nr 1522 ynmax = this%inny - nr 1523 DO iy = 1, this%outny 1524 DO ix = 1, this%outnx 1525 IF (this%inter_index_x(ix,iy) < xnmin .OR. & 1526 this%inter_index_x(ix,iy) > xnmax .OR. & 1527 this%inter_index_y(ix,iy) < ynmin .OR. & 1528 this%inter_index_y(ix,iy) > ynmax) THEN 1529 this%inter_index_x(ix,iy) = imiss 1530 this%inter_index_y(ix,iy) = imiss 1536 CALL l4f_category_log(this%category, l4f_debug, & 1537 'stencilinter: stencil size '//t2c(n*n)) 1538 CALL l4f_category_log(this%category, l4f_debug, & 1539 'stencilinter: stencil points '//t2c(count(this%stencil))) 1545 ELSE IF (this%trans%trans_type == 'maskgen') THEN 1547 IF (this%trans%sub_type == 'poly') THEN 1550 CALL get_val(in, nx=this%innx, ny=this%inny) 1551 this%outnx = this%innx 1552 this%outny = this%inny 1555 ALLOCATE(this%inter_index_x(this%innx,this%inny), & 1556 this%inter_index_y(this%innx,this%inny)) 1557 this%inter_index_x(:,:) = imiss 1558 this%inter_index_y(:,:) = 1 1567 inside_x: DO i = 1, this%innx 1568 point = georef_coord_new(x=out%dim%lon(i,j), y=out%dim%lat(i,j)) 1570 DO n = nprev, this%trans%poly%arraysize 1571 IF (inside(point, this%trans%poly%array(n))) THEN 1572 this%inter_index_x(i,j) = n 1577 DO n = nprev-1, 1, -1 1578 IF (inside(point, this%trans%poly%array(n))) THEN 1579 this%inter_index_x(i,j) = n 1590 ELSE IF (this%trans%sub_type == 'grid') THEN 1593 CALL copy(out, lout) 1596 CALL get_val(in, nx=this%innx, ny=this%inny) 1597 this%outnx = this%innx 1598 this%outny = this%inny 1599 CALL get_val(lout, nx=nx, ny=ny, & 1600 xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax) 1603 ALLOCATE(this%inter_index_x(this%innx,this%inny), & 1604 this%inter_index_y(this%innx,this%inny)) 1610 CALL this%find_index(lout, .true., & 1611 nx, ny, xmin, xmax, ymin, ymax, & 1612 out%dim%lon, out%dim%lat, .false., & 1613 this%inter_index_x, this%inter_index_y) 1615 WHERE(c_e(this%inter_index_x(:,:))) 1616 this%inter_index_x(:,:) = this%inter_index_x(:,:) + & 1617 (this%inter_index_y(:,:)-1)*nx 1625 ELSE IF (this%trans%trans_type == 'polyinter') THEN 1631 CALL get_val(in, nx=this%innx, ny=this%inny) 1632 this%outnx = this%innx 1633 this%outny = this%inny 1636 ALLOCATE(this%inter_index_x(this%innx,this%inny), & 1637 this%inter_index_y(this%innx,this%inny)) 1638 this%inter_index_x(:,:) = imiss 1639 this%inter_index_y(:,:) = 1 1648 inside_x_2: DO i = 1, this%innx 1649 point = georef_coord_new(x=out%dim%lon(i,j), y=out%dim%lat(i,j)) 1651 DO n = nprev, this%trans%poly%arraysize 1652 IF (inside(point, this%trans%poly%array(n))) THEN 1653 this%inter_index_x(i,j) = n 1658 DO n = nprev-1, 1, -1 1659 IF (inside(point, this%trans%poly%array(n))) THEN 1660 this%inter_index_x(i,j) = n 1673 ELSE IF (this%trans%trans_type == 'metamorphosis') THEN 1676 CALL get_val(in, nx=this%innx, ny=this%inny) 1677 this%outnx = this%innx 1678 this%outny = this%inny 1680 IF (this%trans%sub_type == 'maskvalid' .OR. this%trans%sub_type == 'maskinvalid') THEN 1682 IF (.NOT. PRESENT(maskgrid)) THEN 1683 CALL l4f_category_log(this%category,l4f_error, & 1684 'grid_transform_init maskgrid argument missing for metamorphosis:'// & 1685 trim(this%trans%sub_type)// ' transformation') 1690 IF (this%innx /= SIZE(maskgrid,1) .OR. this%inny /= SIZE(maskgrid,2)) THEN 1691 CALL l4f_category_log(this%category,l4f_error, & 1692 'grid_transform_init mask non conformal with input field') 1693 CALL l4f_category_log(this%category,l4f_error, & 1694 'mask: '//t2c( SIZE(maskgrid,1))// 'x'//t2c( SIZE(maskgrid,2))// & 1695 ' input field:'//t2c(this%innx)// 'x'//t2c(this%inny)) 1700 ALLOCATE(this%point_mask(this%innx,this%inny)) 1702 IF (this%trans%sub_type == 'maskvalid') THEN 1705 IF (.NOT. PRESENT(maskbounds)) THEN 1706 this%point_mask(:,:) = c_e(maskgrid(:,:)) 1707 ELSE IF ( SIZE(maskbounds) < 2) THEN 1708 this%point_mask(:,:) = c_e(maskgrid(:,:)) 1710 this%point_mask(:,:) = c_e(maskgrid(:,:)) .AND. & 1711 maskgrid(:,:) > maskbounds(1) .AND. & 1712 maskgrid(:,:) <= maskbounds( SIZE(maskbounds)) 1715 this%point_mask(:,:) = .NOT.c_e(maskgrid(:,:)) 1720 ELSE IF (this%trans%sub_type == 'lemaskinvalid' .OR. & 1721 this%trans%sub_type == 'ltmaskinvalid' .OR. & 1722 this%trans%sub_type == 'gemaskinvalid' .OR. & 1723 this%trans%sub_type == 'gtmaskinvalid') THEN 1726 this%val_mask = maskgrid 1729 ELSE IF (this%trans%sub_type == 'setinvalidto') THEN 1731 IF (.NOT. PRESENT(maskbounds)) THEN 1732 CALL l4f_category_log(this%category,l4f_error, & 1733 'grid_transform_init maskbounds missing for metamorphosis:'// & 1734 trim(this%trans%sub_type)// ' transformation') 1736 ELSE IF ( SIZE(maskbounds) < 1) THEN 1737 CALL l4f_category_log(this%category,l4f_error, & 1738 'grid_transform_init maskbounds empty for metamorphosis:'// & 1739 trim(this%trans%sub_type)// ' transformation') 1742 this%val1 = maskbounds(1) 1744 CALL l4f_category_log(this%category, l4f_debug, & 1745 "grid_transform_init setting invalid data to "//t2c(this%val1)) 1751 ELSE IF (this%trans%sub_type == 'settoinvalid') THEN 1753 IF (.NOT. PRESENT(maskbounds)) THEN 1754 CALL l4f_category_log(this%category,l4f_error, & 1755 'grid_transform_init maskbounds missing for metamorphosis:'// & 1756 trim(this%trans%sub_type)// ' transformation') 1759 ELSE IF ( SIZE(maskbounds) < 2) THEN 1760 CALL l4f_category_log(this%category,l4f_error, & 1761 'grid_transform_init maskbounds must have at least 2 elements for metamorphosis:'// & 1762 trim(this%trans%sub_type)// ' transformation') 1766 this%val1 = maskbounds(1) 1767 this%val2 = maskbounds( SIZE(maskbounds)) 1769 CALL l4f_category_log(this%category, l4f_debug, & 1770 "grid_transform_init setting to invalid interval ]"//t2c(this%val1)// ','// & 1771 t2c(this%val2)// ']') 1785 SUBROUTINE outgrid_setup() 1788 CALL griddim_setsteps(out) 1790 CALL get_val(in, proj=proj_in, component_flag=cf_i) 1791 CALL get_val(out, proj=proj_out, component_flag=cf_o) 1792 IF (proj_in == proj_out) THEN 1795 CALL set_val(out, component_flag=cf_i) 1800 CALL l4f_category_log(this%category,l4f_warn, & 1801 'trying to interpolate a grid with component flag 1 to a grid on a different projection') 1802 CALL l4f_category_log(this%category,l4f_warn, & 1803 'vector fields will probably be wrong') 1805 CALL set_val(out, component_flag=cf_i) 1809 CALL griddim_set_central_lon(in, griddim_central_lon(out)) 1811 END SUBROUTINE outgrid_setup 1813 END SUBROUTINE grid_transform_init 1858 SUBROUTINE grid_transform_grid_vol7d_init(this, trans, in, v7d_out, & 1859 maskgrid, maskbounds, find_index, categoryappend) 1860 TYPE(grid_transform), INTENT(out) :: this 1861 TYPE(transform_def), INTENT(in) :: trans 1862 TYPE(griddim_def), INTENT(in) :: in 1863 TYPE(vol7d), INTENT(inout) :: v7d_out 1864 REAL, INTENT(in), OPTIONAL :: maskgrid(:,:) 1865 REAL, INTENT(in), OPTIONAL :: maskbounds(:) 1866 PROCEDURE(basic_find_index), POINTER, OPTIONAL :: find_index 1867 CHARACTER(len=*), INTENT(in), OPTIONAL :: categoryappend 1869 INTEGER :: ix, iy, n, nm, nr, nprev, nmaskarea, xnmin, xnmax, ynmin, ynmax, & 1871 DOUBLE PRECISION :: xmin, xmax, ymin, ymax, r2, lonref 1872 DOUBLE PRECISION, ALLOCATABLE :: lon1(:), lat1(:), lon(:,:), lat(:,:) 1873 REAL, ALLOCATABLE :: lmaskbounds(:) 1874 TYPE(georef_coord) :: point 1875 TYPE(griddim_def) :: lin 1878 IF ( PRESENT(find_index)) THEN 1879 IF ( ASSOCIATED(find_index)) THEN 1880 this%find_index => find_index 1883 CALL grid_transform_init_common(this, trans, categoryappend) 1885 CALL l4f_category_log(this%category, l4f_debug, "grid_transform vg6d-v7d") 1889 CALL get_val(trans, time_definition=time_definition) 1890 IF (.NOT. c_e(time_definition)) THEN 1894 IF (this%trans%trans_type == 'inter') THEN 1896 IF (this%trans%sub_type == 'near' .OR. this%trans%sub_type == 'bilin' & 1897 .OR. this%trans%sub_type == 'shapiro_near') THEN 1900 CALL get_val(lin, nx=this%innx, ny=this%inny) 1901 this%outnx = SIZE(v7d_out%ana) 1904 ALLOCATE (this%inter_index_x(this%outnx,this%outny),& 1905 this%inter_index_y(this%outnx,this%outny)) 1906 ALLOCATE(lon(this%outnx,1),lat(this%outnx,1)) 1908 CALL getval(v7d_out%ana(:)%coord,lon=lon(:,1),lat=lat(:,1)) 1910 lonref = 0.5d0*(maxval(lon(:,1), mask=c_e(lon(:,1))) + minval(lon(:,1), mask=c_e(lon(:,1)))) 1911 CALL griddim_set_central_lon(lin, lonref) 1912 CALL get_val(lin, xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax) 1914 IF (this%trans%sub_type == 'bilin') THEN 1915 CALL this%find_index(lin, .false., & 1916 this%innx, this%inny, xmin, xmax, ymin, ymax, & 1917 lon, lat, this%trans%extrap, & 1918 this%inter_index_x, this%inter_index_y) 1920 ALLOCATE(this%inter_x(this%innx,this%inny),this%inter_y(this%innx,this%inny)) 1921 ALLOCATE(this%inter_xp(this%outnx,this%outny),this%inter_yp(this%outnx,this%outny)) 1923 CALL griddim_gen_coord(lin, this%inter_x, this%inter_y) 1924 CALL proj(lin, lon, lat, this%inter_xp, this%inter_yp) 1927 CALL this%find_index(lin, .true., & 1928 this%innx, this%inny, xmin, xmax, ymin, ymax, & 1929 lon, lat, this%trans%extrap, & 1930 this%inter_index_x, this%inter_index_y) 1932 IF (this%trans%trans_type == 'intersearch') THEN 1933 ALLOCATE(this%inter_x(this%innx,this%inny),this%inter_y(this%innx,this%inny)) 1934 ALLOCATE(this%inter_xp(this%outnx,this%outny),this%inter_yp(this%outnx,this%outny)) 1936 CALL griddim_gen_coord(lin, this%inter_x, this%inter_y) 1937 CALL proj(lin, lon, lat, this%inter_xp, this%inter_yp) 1948 ELSE IF (this%trans%trans_type == 'polyinter') THEN 1950 CALL get_val(in, nx=this%innx, ny=this%inny) 1952 ALLOCATE(this%inter_index_x(this%innx,this%inny), & 1953 this%inter_index_y(this%innx,this%inny)) 1954 this%inter_index_x(:,:) = imiss 1955 this%inter_index_y(:,:) = 1 1961 this%outnx = this%trans%poly%arraysize 1963 CALL delete(v7d_out) 1964 CALL init(v7d_out, time_definition=time_definition) 1965 CALL vol7d_alloc(v7d_out, nana=this%outnx) 1968 ALLOCATE(lon(this%outnx,1)) 1969 CALL getval(v7d_out%ana(:)%coord,lon=lon(:,1)) 1970 lonref = 0.5d0*(maxval(lon(:,1), mask=c_e(lon(:,1))) + minval(lon(:,1), mask=c_e(lon(:,1)))) 1971 CALL griddim_set_central_lon(lin, lonref) 1976 CALL poly_to_coordinates(this%trans%poly, v7d_out) 1981 DO iy = 1, this%inny 1982 inside_x: DO ix = 1, this%innx 1983 point = georef_coord_new(x=lin%dim%lon(ix,iy), y=lin%dim%lat(ix,iy)) 1985 DO n = nprev, this%trans%poly%arraysize 1986 IF (inside(point, this%trans%poly%array(n))) THEN 1987 this%inter_index_x(ix,iy) = n 1992 DO n = nprev-1, 1, -1 1993 IF (inside(point, this%trans%poly%array(n))) THEN 1994 this%inter_index_x(ix,iy) = n 2006 DO n = 1, this%trans%poly%arraysize 2007 CALL l4f_category_log(this%category, l4f_debug, & 2008 'Polygon: '//t2c(n)// ' grid points: '// & 2009 t2c(count(this%inter_index_x(:,:) == n)))
|