Changeset 5753 for LMDZ6/trunk/libf/misc/strings_mod.f90
- Timestamp:
- Jul 2, 2025, 3:51:41 PM (8 days ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
LMDZ6/trunk/libf/misc/strings_mod.f90
r5752 r5753 1598 1598 1599 1599 !============================================================================================================================== 1600 !=== DISPLAY OUTLIERS IN TABLES =============================================================================================== 1601 !============================================================================================================================== 1602 !=== lerr = dispOutliers_1(ll(:), a(:[:]), n(:), err_msg, nam(:), sub, nRowmax, nColMax, unit) 1603 !=== * ll linearized mask of outliers 1604 !=== * a linearized fields: 1605 !=== a(:) all the fields are linearized (all contane 1606 !=== Behaviour depends on ll(:), n(:) and nam(:). We note hereafter nv = SIZE(nam). 1607 !=== 1608 !=== 1) if SIZE(ll) == PRODUCT(n) and nv==1 or "nam" is unspecified: outliers of a single variable are displayed 1609 !=== i[,j[,k]] | nam | 1610 !=== ----------+-----------------+ 1611 !=== *[,*[,*]] | val(i[,j[,k]]) | 1612 !=== ... | ... | 1613 !=== 1614 !=== 1615 !=== 2) if SIZE(ll) == PRODUCT(n) and nv>1: "nv" tables of outliers are displayed, each having its own mask 1616 !=== i[,j] | var(1) 1617 !=== ------+-------------- 1618 !=== *[,*] | val(i[,j],1) 1619 !=== ... | ... 1620 !=== 1621 !=== ... 1622 !=== 1623 !=== i[,j] | var(nv) 1624 !=== ------+--------------- 1625 !=== *[,*] | val(i[,j],nv) 1626 !=== ... | ... 1627 !=== 1628 !=== 1629 !=== 3) if SIZE(ll) = PRODUCT(n(1:SIZE(n)-1): outliers of "nv" variables are displayed, all with mask "ll(:)" 1630 !=== i[,j] | var(1) | var(2) | ... | var(nv) 1631 !=== ------+--------------+---------------+-- ... --+--------------- 1632 !=== *[,*] | val(i[,j],1) | val(i[,j],2) | ... | val(i[,j],nv) 1633 !=== ... | ... | ... | ... | ... 1634 !=== 1635 !=== NOTES: 1636 !=== * in cases 2 and 3, SIZE(nam) MUST be equal to n(SIZE(n)). 1637 !=== * for the sake of readability, narrow tables (compared to the max. width "nColMax") are horizontally stacked. 1638 !=== Here is the result in the case 1: 1639 !=== i[,j[,k]] | nam | i[,j[,k]] | nam | ... | i[,j[,k]] | nam 1640 !=== ----------+-----------------+-----------+-----------------+-- ... --+-----------+----------------- 1641 !=== *[,*[,*]] | val(i[,j[,k]]) | *[,*[,*]] | val(i[,j[,k]]) | ... | *[,*[,*]] | val(i[,j[,k]]) 1642 !=== ... | ... | ... | ... | ... | ... | ... 1643 !=== * conversly, in case 3, too wide tables are displayed as several sub-tables. 1644 !=== * too long tables are truncated to nRowMax lines (excluding titles lines). 1645 !============================================================================================================================== 1646 LOGICAL FUNCTION dispOutliers_1(ll, a, n, err_msg, nam, sub, nRowmax, nColMax, unit) RESULT(lerr) 1647 IMPLICIT NONE 1648 ! Display outliers list in tables 1649 ! If "nam" is supplied, it means the last index is for tracers => one table each tracer for rank > 2. 1650 LOGICAL, INTENT(IN) :: ll(:) !--- Linearized mask of outliers 1651 REAL, INTENT(IN) :: a(:) !--- Linearized array of values 1652 INTEGER, INTENT(IN) :: n(:) !--- Profile before linearization 1653 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: err_msg, nam(:), sub !--- Error message, variables and calling subroutine names 1654 INTEGER, OPTIONAL, INTENT(IN) :: nRowMax !--- Maximum number of lines to display (default: all) 1655 INTEGER, OPTIONAL, INTENT(IN) :: nColMax !--- Maximum number of characters per line (default: 2048) 1656 INTEGER, OPTIONAL, INTENT(IN) :: unit !--- Output unit (def: lunout) 1657 !------------------------------------------------------------------------------------------------------------------------------ 1658 CHARACTER(LEN=maxlen), ALLOCATABLE :: t(:), vnm(:), c(:,:) 1659 LOGICAL, ALLOCATABLE :: m(:), ld(:) 1660 INTEGER, ALLOCATABLE :: ki(:), kj(:) 1661 INTEGER :: rk, ib, ie, itr, nm, unt, nRmx, nCmx, iv, nv, np 1662 CHARACTER(LEN=maxlen) :: mes, subn, fm='(f12.9)', p 1663 lerr = .FALSE. 1664 1665 IF(.NOT.ANY(ll)) RETURN !--- No outliers -> finished 1666 1667 mes = 'outliers found'; IF(PRESENT(err_msg)) mes = err_msg !--- Error message 1668 vnm = ['a']; IF(PRESENT(nam)) vnm = nam !--- Variables names 1669 subn= 'dispOutliers'; IF(PRESENT(sub)) subn= sub !--- Calling subroutine name 1670 nRmx= SIZE(a); IF(PRESENT(nRowMax)) nRmx=MIN(nRmx,nRowMax)!--- Maximum number of lines to print 1671 nCmx= 2048; IF(PRESENT(nColMax)) nCmx=MIN(nCmx,nColMax)!--- Maximum number of characters each line 1672 unt = lunout; IF(PRESENT(unit)) unt = unit !--- Unit to print messages 1673 1674 rk = SIZE(n) !--- Rank of "a" before linearization 1675 nv = SIZE(vnm) !--- Number of variables 1676 np = PRODUCT(n(1:rk-1)) !--- Number of points per var (in the multiple vars case) 1677 lerr = rk>3; CALL msg('can display field with rank <=3 only !', subn, lerr, unt); IF(lerr) RETURN 1678 lerr = n(rk) == 1; CALL msg('degenerated last dim: n(SIZE(n)) = 1 !', subn, lerr, unt); IF(lerr) RETURN 1679 lerr = nv/=1 .AND. nv/=n(rk); CALL msg('SIZE(nam) /= 1 and /= last "n" element', subn, lerr, unt); IF(lerr) RETURN 1680 lerr = SIZE(a) /= PRODUCT(n); CALL msg('profile "n" does not match "a" and "ll', subn, lerr, unt); IF(lerr) RETURN 1681 lerr = ALL([PRODUCT(n),np] /= SIZE(ll)) 1682 CALL msg('ll" length must be either PROD(n) or PROD(n(1:rk-1))', subn, lerr, unt); IF(lerr) RETURN 1683 1684 !============================================================================================================================ 1685 IF(SIZE(ll) == PRODUCT(n)) THEN !=== ll(:) IS A MASK FOR THE WHOLE a(:) VECTOR =========== 1686 !============================================================================================================================ 1687 p = 's'//REPEAT('r',nv) !--- Display map: one string, "nv" reals 1688 IF(nv == 1) THEN !=== SINGLE VARIABLE 1689 CALL buildTitle(n, vnm, t) !--- Build titles list "t" for a single variable 1690 CALL buildCoord(n, ll, c) !--- Masked ("ll") coordinates vector "c" 1691 lerr = dispTable(p, t, s=c, r=cat(PACK(a,ll)), rFmt=fm, nRowMax=nRmx, nColMax=nCmx, nHead=1, unit=unt, sub=subn) 1692 ELSE !=== MULTIPLE VARIABLES 1693 DO iv = 1, nv 1694 CALL buildTitle(n, vnm(iv:iv), t) !--- Titles list "t" for the "iv"th variables 1695 CALL buildCoord(n(1:rk-1), ll, c) !--- Masked ("ll") coordinates vector "c" 1696 ib = 1+(iv-1)*np; ie = ib+np 1697 lerr = dispTable(p, t, s=c, r=cat(PACK(a(ib:ie),ll(ib:ie))), rFmt=fm, nRowMax=nRmx, nColMax=nCmx, nHead=1, & 1698 unit=unt, sub=subn) 1699 CALL msg("can't display outliers table", subn, lerr, unt); IF(lerr) RETURN 1700 END DO 1701 END IF 1702 !============================================================================================================================ 1703 ELSE !=== ll(:) IS A MASK FOR EACH TRACER STACKED IN a(:) VECTOR 1704 !============================================================================================================================ 1705 CALL buildTitle(n, vnm, t) !--- Build titles list "t" for all the variable 1706 CALL duplicate(ll, nv, ld) !--- "ll" concatenated "nv" times 1707 CALL buildCoord(n(1:rk-1), ll, c) !--- Masked ("ll") coordinates vector "c" 1708 lerr = dispTable(p, t, s=c, r=RESHAPE(PACK(a,ld),[np,nv]), rFmt=fm, nRowMax=nRmx, nColMax=nCmx, nHead=1,unit=unt,sub=subn) 1709 !============================================================================================================================ 1710 END IF 1711 !============================================================================================================================ 1712 CALL msg("can't display outliers table", subn, lerr, unt) 1713 1714 CONTAINS 1715 1716 SUBROUTINE buildTitle(n, vname, title) !=== BUILD TITLES: [COORD. NAME, THE VARIABLE(S) NAME(S)] 1717 INTEGER, INTENT(IN) :: n(:) 1718 CHARACTER(LEN=maxlen), INTENT(IN) :: vname(:) 1719 CHARACTER(LEN=maxlen), ALLOCATABLE, INTENT(OUT) :: title(:) 1720 INTEGER :: rk 1721 rk = SIZE(n) 1722 ALLOCATE(title(1+SIZE(vname))) 1723 title(2:SIZE(vname)+1) = vname 1724 title(1) = 'i' 1725 IF(rk >= 2) title(1) = TRIM(title(1))//', j' 1726 IF(rk >= 3) title(1) = TRIM(title(1))//', k' 1727 END SUBROUTINE buildTitle 1728 1729 SUBROUTINE buildCoord(n, mask, coord) !=== BUILD MASKED COORDINATES OK FOR "s" ARG OF dispTable 1730 INTEGER, INTENT(IN) :: n(:) 1731 LOGICAL, INTENT(IN) :: mask(:) 1732 CHARACTER(LEN=maxlen), ALLOCATABLE, INTENT(OUT) :: coord(:,:) 1733 CHARACTER(LEN=maxlen) :: sj, sk 1734 INTEGER :: i, j, k, m(3), rk, ic 1735 rk = SIZE(n) 1736 m(:) = 1; m(1:rk) = n(:) 1737 ALLOCATE(coord(1,COUNT(mask))) 1738 ic = 0 1739 DO k = 1, m(3); sk = ', '//num2str(k) 1740 DO j = 1, m(2); sj = ', '//num2str(j) 1741 DO i = 1, m(1) 1742 IF(.NOT.mask(i+m(1)*(j+m(2)*k))) CYCLE 1743 ic = ic+1 1744 coord(ic,1) = num2str(i) 1745 IF(rk >= 2) coord(ic,1) = TRIM(coord(ic,1))//TRIM(sj) 1746 IF(rk >= 3) coord(ic,1) = TRIM(coord(ic,1))//TRIM(sk) 1747 END DO 1748 END DO 1749 END DO 1750 END SUBROUTINE buildCoord 1751 1752 END FUNCTION dispOutliers_1 1753 !============================================================================================================================== 1754 LOGICAL FUNCTION dispOutliers_2(ll, a, n, err_msg, nam, sub, nRowmax, nColMax, unit) RESULT(lerr) 1755 IMPLICIT NONE 1756 ! Display outliers list in tables 1757 ! If "nam" is supplied, it means the last index is for tracers => one table each tracer for rank > 2. 1758 LOGICAL, INTENT(IN) :: ll(:) !--- Linearized mask of outliers 1759 REAL, INTENT(IN) :: a(:,:) !--- Linearized array of values 1760 INTEGER, INTENT(IN) :: n(:) !--- Profile before linearization 1761 CHARACTER(LEN=*), OPTIONAL, INTENT(IN) :: err_msg, nam(:), sub !--- Error message, variables and calling subroutine names 1762 INTEGER, OPTIONAL, INTENT(IN) :: nRowMax !--- Maximum number of lines to display (default: all) 1763 INTEGER, OPTIONAL, INTENT(IN) :: nColMax !--- Maximum number of characters per line (default: 2048) 1764 INTEGER, OPTIONAL, INTENT(IN) :: unit !--- Output unit (def: lunout) 1765 !------------------------------------------------------------------------------------------------------------------------------ 1766 lerr = dispOutliers_1(ll, PACK(a, MASK=.TRUE.), n, err_msg, nam, sub, nRowmax, nColMax, unit) 1767 END FUNCTION dispOutliers_2 1768 !============================================================================================================================== 1769 1770 1771 !============================================================================================================================== 1600 1772 !=== Reduce an algebrical expression (basic operations and parenthesis) to a single number (string format) ==================== 1601 1773 !==============================================================================================================================
Note: See TracChangeset
for help on using the changeset viewer.