Changeset 1036 in lmdz_wrf
- Timestamp:
- Aug 21, 2016, 1:01:03 AM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/tools/model_graphics.py
r1032 r1036 637 637 Tunits = config['CFunitstime'] 638 638 # opsur = operation surnames 639 640 639 opsur = gen.get_specdictionary_HMT(config, H='opsur_',M='',T='') 641 640 Opsurs = {} … … 726 725 # temporal accumulated values 727 726 print " " + fname + ": kind '" + op + "' not ready !!" 728 wrongstats.appen (CFvarn + '_' + opers)727 wrongstats.append(CFvarn + '_' + opers) 729 728 break 730 729 elif op == 'direct': … … 760 759 # latitudinal mean values 761 760 print " " + fname + ": kind '" + op + "' not ready !!" 762 wrongstats.appen (CFvarn + '_' + opers)761 wrongstats.append(CFvarn + '_' + opers) 763 762 break 764 763 elif op =='Lsec': 765 764 # latitudinal section (latitudinal value must be given, [var]@[lat]) 766 765 print " " + fname + ": kind '" + op + "' not ready !!" 767 wrongstats.appen (CFvarn + '_' + opers)766 wrongstats.append(CFvarn + '_' + opers) 768 767 break 769 768 elif op =='lmean': 770 769 # longitudinal mean values 771 770 print " " + fname + ": kind '" + op + "' not ready !!" 772 wrongstats.appen (CFvarn + '_' + opers)771 wrongstats.append(CFvarn + '_' + opers) 773 772 break 774 773 elif op =='lsec': 775 774 # longitudinal section (longitudinal value must be given, [var]@[lon]) 776 775 print " " + fname + ": kind '" + op + "' not ready !!" 777 wrongstats.appen (CFvarn + '_' + opers)776 wrongstats.append(CFvarn + '_' + opers) 778 777 break 779 778 elif op == 'pinterp': … … 1733 1732 headerf2 = vals2[0] 1734 1733 1735 diffops[vnop] = [ headerf1, headerf2]1734 diffops[vnop] = [mods[0], mods[1], exps[0], exps[1], headerf1, headerf2] 1736 1735 1737 1736 Ndiffop = Ndiffop + 1 … … 1764 1763 headerf2 = vals2[0] 1765 1764 1766 diffvars[vnop] = [ headerf1, headerf2]1765 diffvars[vnop] = [mods[0], mods[1], exps[0], exps[1], headerf1, headerf2] 1767 1766 1768 1767 Ndiffvar = Ndiffvar + 1 … … 1808 1807 1809 1808 return diffs, Ndiffs 1809 1810 def compute_op_diffs(config, diffallop, odir, diffscr, debug): 1811 """ Function to compute operation differences 1812 config= experiment configuration 1813 diffallop= dictonary with the differences to compute 1814 odir= output folder 1815 diffscr= wether it should be done from the scratch 1816 """ 1817 fname = 'compute_op_diffs' 1818 1819 # output folder 1820 ofold = config['ofold'] 1821 1822 # Home of the python scripts 1823 pyH = config['pyHOME'] 1824 1825 # opsur = operation surnames 1826 opsur = gen.get_specdictionary_HMT(config, H='opsur_',M='',T='') 1827 Opsurs = {} 1828 for opk in opsur: 1829 opn = opk.split('_')[1] 1830 vals = opsur[opk] 1831 Opsurs[opn] = vals.split(':') 1832 1833 # Getting in working dir 1834 os.chdir(odir) 1835 1836 # CF dimensions 1837 CFdims = ['lon', 'lat', 'pres', 'time'] 1838 1839 # Trakcing file 1840 trkobjf = open(odir + '/all_diffop.inf', 'a') 1841 1842 for vnop in diffallop.keys(): 1843 vn = vnop.split('_')[0] 1844 op = vnop.split('_')[1] 1845 opS = op.replace('+','_') 1846 1847 # `p' header add related to 'pinterp' 1848 if opS.find('pinterp') != -1: SgP = 'p' 1849 else: SgP = '' 1850 1851 # Variable name within the file 1852 vninF = varnoper(vn, op, Opsurs) 1853 1854 vals = diffallop[vnop] 1855 mod1 = vals[0] 1856 mod2 = vals[1] 1857 exp1 = vals[2] 1858 exp2 = vals[3] 1859 headerf1 = vals[4] 1860 headerf2 = vals[5] 1861 modexpdiff = mod2 + '/' + exp2 + ' - ' + mod1 + '/' + exp1 1862 modexpdiffS = mod2 + '-' + exp2 + '_' + mod1 + '-' + exp1 1863 1864 ifile1 = ofold + '/' + mod1 + '/' + exp1 + '/' + vn + '_' + headerf1 + SgP + \ 1865 '_' + opS + '.nc' 1866 ifile2 = ofold + '/' + mod2 + '/' + exp2 + '/' + vn + '_' + headerf2 + SgP + \ 1867 '_' + opS + '.nc' 1868 difffilen = odir + '/' + vn + '_diffop_' + modexpdiffS + '_' + opS + '.nc' 1869 1870 if diffscr: 1871 sout = sub.call('rm ' + difffilen + ' >& /dev/null', shell=True) 1872 1873 if not os.path.isfile(difffilen): 1874 if debug: 1875 print " Computing operation difference '" + op + "' of '" + vn + \ 1876 "' for: '" + modexpdiff 1877 print " var in file: '" + vninF + "'" 1878 1879 dfiles = 'add|' + ifile2 + '|' + vninF + ',sub|' + ifile1 + '|' + vninF 1880 values = '|'.join(CFdims) + '@' + dfiles 1881 pyins = 'python ' + pyH + "/nc_var.py -o compute_opersvarsfiles -S '" + \ 1882 values + "' -v " + vninF 1883 1884 try: 1885 with gen.Capturing() as output: 1886 ncvar.compute_opersvarsfiles(values,vninF) 1887 except: 1888 print errmsg 1889 print 'ncvar.compute_opersvarsfiles(' + values + ',' + vninF + ')' 1890 for sout in output: print sout 1891 quit(-1) 1892 1893 sout = sub.call('mv opersvarsfiles_'+vninF+'.nc ' + difffilen, shell=True) 1894 1895 # keeping all differences 1896 trkobjf.write('\n') 1897 trkobjf.write("#" + vn + ' ' + op + '\n') 1898 trkobjf.write( pyins + '\n') 1899 1900 trkobjf.close() 1901 1902 return 1903 1904 def compute_diff_statistics(Ecnf, filen, ofold, varn, Opers, scr, db): 1905 """ Function to compute statistics from var diff files 1906 Ecnf= dictionary with the configuration of the experiment 1907 filen= variable difference file to use 1908 ofold= directory to write the output files 1909 varn= name of the variable 1910 Opers= kind of operation: (as possible multiple consecutive combination of operations separated by '+' 1911 [calc1]+[calc2] will compute first [calc1] and then [calc2] 1912 acc: temporal accumulated values 1913 diff: differences between models 1914 direct: no statistics 1915 last: last temporal value 1916 Lmean: latitudinal mean values 1917 Lsec: latitudinal section (latitudinal value must be given, [var]@[lat]) 1918 lmean: longitudinal mean values 1919 lsec: longitudinal section (longitudinal value must be given, [var]@[lat]) 1920 pinterp: pressure interpolation (to the given $plevels) 1921 tmean: temporal mean values 1922 turb: Taylor's turbulence decomposition value 1923 xmean: x-axis mean values 1924 ymean: y-axis mean values 1925 zsum: vertical aggregated values 1926 scr= should it be done from the scratch? 1927 """ 1928 fname='compute_diff_statistics' 1929 1930 # Full header of file 1931 Lfilen = len(filen) 1932 Hfile = filen[0:Lfilen-3] 1933 1934 # CF dimension-variables name 1935 OpersS = '+'.join(Opers) 1936 if OpersS.find('pinterp') != -1: 1937 varnCFs = ['lon', 'lat', 'pres', 'time'] 1938 else: 1939 varnCFs = ['lon', 'lat', 'time'] 1940 1941 # Variable-dimension CF dictionary 1942 CFdimvardict = {'lon': 'lon', 'lat': 'lat', 'pres': 'pres', 'time': 'time'} 1943 1944 # Python scripts HOME 1945 pyH = Ecnf['pyHOME'] 1946 1947 # opsur = operation surnames 1948 opsur = gen.get_specdictionary_HMT(Ecnf, H='opsur_',M='',T='') 1949 Opsurs = {} 1950 for opk in opsur: 1951 opn = opk.split('_')[1] 1952 vals = opsur[opk] 1953 Opsurs[opn] = vals.split(':') 1954 1955 # Getting in working dir 1956 os.chdir(ofold) 1957 1958 # File to keep track of all the statistics of var differences 1959 otrackf = open(ofold + '/all_vardiffstatistics.inf', 'a') 1960 1961 if db: 1962 print " computing statistics of diff variable: '", varn ,"' operation '"+ \ 1963 OpersS + "' using file '" + filen + " ...'" 1964 1965 for op in Opers: 1966 # File name from previous operations, and name of the variable within the 1967 # file (some operations change the name of the variable) 1968 if op == Opers[0]: 1969 Fopers = op 1970 prevfile = filen 1971 vninF = varn 1972 else: 1973 Fopers = Fopers + '_' + op 1974 prevfile = fileon 1975 fileon = Hfile + '_' + Fopers + '.nc' 1976 1977 SvarnCFs = ',' + ','.join(varnCFs) 1978 CFvarnp = vninF + SvarnCFs 1979 1980 if scr: 1981 sout = sub.call('rm ' + fileon + ' >& /dev/null', shell=True) 1982 1983 # Just produce file in case output file does not exist 1984 if not os.path.isfile(fileon): 1985 if db: 1986 print ' ' + fname + ": creation of file '" + fileon + "' ..." 1987 dofile = True 1988 else: 1989 dofile = False 1990 1991 # Variables to be kept in the final file 1992 varkeep = [] 1993 1994 if op == 'acc': 1995 # temporal accumulated values 1996 print " " + fname + ": kind '" + op + "' not ready !!" 1997 wrongstats.append(varn + '_' + opers) 1998 break 1999 elif op == 'direct': 2000 # no statistics 2001 if dofile: 2002 sout = sub.call('mv ' + prevfile + ' ' + fileon, shell=True) 2003 elif op == 'last': 2004 # last temporal value 2005 vals='time,-9,0,0' 2006 if dofile: 2007 try: 2008 with gen.Capturing() as output: 2009 ncvar.DataSetSection(vals,prevfile) 2010 except: 2011 print 'DataSetSection('+vals+',', prevfile, ')' 2012 for sout in output: print sout 2013 quit(-1) 2014 2015 if db: 2016 for sout in output: print sout 2017 2018 hprevfile = prevfile[0:len(prevfile)-3] 2019 2020 sout = sub.call('mv ' + hprevfile + '_time_B-9-E0-I0.nc ' + fileon, \ 2021 shell=True) 2022 2023 # Keeping the operations 2024 pyins=pyH + "/nc_var.py -o DataSetSection -S '" + vals + "' -f " + \ 2025 prevfile 2026 otrackf.write("\n") 2027 otrackf.write("# " + varn + " " + Fopers + "\n") 2028 otrackf.write(pyins + "\n") 2029 2030 elif op =='Lmean': 2031 # latitudinal mean values 2032 print " " + fname + ": kind '" + op + "' not ready !!" 2033 wrongstats.append(varn + '_' + opers) 2034 break 2035 elif op =='Lsec': 2036 # latitudinal section (latitudinal value must be given, [var]@[lat]) 2037 print " " + fname + ": kind '" + op + "' not ready !!" 2038 wrongstats.append(varn + '_' + opers) 2039 break 2040 elif op =='lmean': 2041 # longitudinal mean values 2042 print " " + fname + ": kind '" + op + "' not ready !!" 2043 wrongstats.append(varn + '_' + opers) 2044 break 2045 elif op =='lsec': 2046 # longitudinal section (longitudinal value must be given, [var]@[lon]) 2047 print " " + fname + ": kind '" + op + "' not ready !!" 2048 wrongstats.append(varn + '_' + opers) 2049 break 2050 elif op == 'tmean': 2051 # temporal mean values 2052 vals='time|-1,time,mean,' + ':'.join(varnCFs) 2053 dims = gen.dictvar_listS(varnCFs,CFdimvardict,',','@') 2054 if dofile: 2055 try: 2056 with gen.Capturing() as output: 2057 ncvar.file_oper_alongdims(vals,prevfile,CFvarnp) 2058 except: 2059 print 'file_oper_alongdims('+vals+',', prevfile, ','+CFvarnp+')' 2060 for sout in output: print sout 2061 quit(-1) 2062 2063 if db: 2064 for sout in output: print sout 2065 2066 sout = sub.call('mv file_oper_alongdims_mean.nc '+fileon, shell=True) 2067 2068 # Keeping the operations 2069 pyins=pyH + "/nc_var.py -o file_oper_alongdims -S '" + vals + \ 2070 "' -f " + prevfile + " -v " + CFvarnp 2071 otrackf.write("\n") 2072 otrackf.write("# " + varn + " " + Fopers + "\n") 2073 otrackf.write(pyins + "\n") 2074 2075 # removing dimension variable-dimension 'time' 2076 varnCFs.remove('time') 2077 2078 varkeep.append('timestats') 2079 2080 # elif op == 'turb': 2081 # # turbulence values 2082 # vals='turbulence|'${CFvarn} 2083 # dims='time@time,'${dnz}'@'${vdnz}',lat@lat,lon@lon,pres@pres' 2084 # pyout=`python ${pyHOME}/diagnostics.py -d ${dims} -v ${vals} -f ${cfiles}` 2085 2086 # # Keeping the operations 2087 # pyins="python "${pyHOME}"/diagnostics.py -d "${dims}" -v '"${vals} 2088 # pyins=${pyins}"' -f ${cfiles}" 2089 # echo " " >> ${odir}/all_statsvars.inf 2090 # echo "# ${CFvarn}" "${vark}" >> ${odir}/all_statsvars.inf 2091 # echo ${pyins} >> ${odir}/all_statsvars.inf 2092 2093 # varkeep=':'${CFvarn}'turb' 2094 2095 elif op == 'xmean': 2096 # x-axis mean values 2097 vals='lon|-1,lon,mean,' + ':'.join(varnCFs) 2098 dims = gen.dictvar_listS(varnCFs,CFdimvardict,',','@') 2099 if dofile: 2100 try: 2101 with gen.Capturing() as output: 2102 ncvar.file_oper_alongdims(vals,prevfile,CFvarnp) 2103 except: 2104 print 'file_oper_alongdims('+vals+',', prevfile, ','+CFvarnp+')' 2105 for sout in output: print sout 2106 quit(-1) 2107 2108 if db: 2109 for sout in output: print sout 2110 2111 sout = sub.call('mv file_oper_alongdims_mean.nc '+fileon, shell=True) 2112 2113 # Keeping the operations 2114 pyins=pyH + "/nc_var.py -o file_oper_alongdims -S '" + vals + \ 2115 "' -f " + prevfile + " -v " + CFvarnp 2116 otrackf.write("\n") 2117 otrackf.write("# " + varn + " " + Fopers + "\n") 2118 otrackf.write(pyins + "\n") 2119 2120 varkeep.append('lonstats') 2121 2122 elif op == 'ymean': 2123 # y-axis mean values 2124 vals='lat|-1,lat,mean,' + ':'.join(varnCFs) 2125 dims = gen.dictvar_listS(varnCFs,CFdimvardict,',','@') 2126 if dofile: 2127 try: 2128 with gen.Capturing() as output: 2129 ncvar.file_oper_alongdims(vals,prevfile,CFvarnp) 2130 except: 2131 print 'file_oper_alongdims('+vals+',', prevfile, ','+CFvarnp+')' 2132 for sout in output: print sout 2133 quit(-1) 2134 2135 if db: 2136 for sout in output: print sout 2137 2138 sout = sub.call('mv file_oper_alongdims_mean.nc '+fileon, shell=True) 2139 2140 # Keeping the operations 2141 pyins=pyH + "/nc_var.py -o file_oper_alongdims -S '" + vals + \ 2142 "' -f " + prevfile + " -v " + CFvarnp 2143 otrackf.write("\n") 2144 otrackf.write("# " + varn + " " + Fopers + "\n") 2145 otrackf.write(pyins + "\n") 2146 2147 varkeep.append('latstats') 2148 2149 elif op == 'zsum': 2150 # vertical aggregated values 2151 print " " + fname + ": kind '" + op + "' not ready !!" 2152 wrongstats.append(varn + '_' + opers) 2153 break 2154 else: 2155 print errmsg 2156 print ' ' + fname + ": operation '" + op + "' not ready !!" 2157 quit(-1) 2158 2159 # End of kind of operation 2160 2161 # Variable name in file (vninF) changed due to operation 2162 # but only if previous operation does not the same 'statistic' 2163 chvn = gen.dictionary_key_list(Opsurs, op) 2164 if chvn is not None: 2165 oldvninF = vninF 2166 vninF = vninF + chvn 2167 CFvarnp = CFvarnp.replace(oldvninF,vninF) 2168 2169 if dofile: 2170 if len(varkeep) > 0: 2171 varkeepS = ',' + ','.join(varkeep) 2172 else: 2173 varkeepS = '' 2174 2175 # Adding such CF dimension variables which might not be in the 2176 # post-operation file 2177 try: 2178 with gen.Capturing() as output: 2179 varinfile = ncvar.ivars(fileon) 2180 except: 2181 print 'ivars('+fileon+')' 2182 for sout in output: print sout 2183 quit(-1) 2184 2185 for CFvn in varnCFs: 2186 if not gen.searchInlist(varinfile, CFvn): 2187 if db: 2188 print ' ' + fname + ": recupering CF variable '" + CFvn + "'" 2189 try: 2190 with gen.Capturing() as output: 2191 ncvar.fvaradd(prevfile+','+CFvn, fileon) 2192 except: 2193 print 'fvaradd(', prevfile, ','+CFvn+','+fileon+')' 2194 for sout in output: print sout 2195 quit(-1) 2196 2197 if db: 2198 for sout in output: print sout 2199 2200 totalvarkeeps = CFvarnp + ',' + ','.join(varnCFs) + varkeepS 2201 try: 2202 with gen.Capturing() as output: 2203 oclean = ncvar.cleaning_varsfile(totalvarkeeps,fileon) 2204 except: 2205 print 'cleaning_varsfile('+totalvarkeeps+','+fileon+')' 2206 for sout in output: print sout 2207 quit(-1) 2208 2209 if db: 2210 for sout in output: print sout 2211 2212 # End of operations 2213 otrackf.close() 2214 2215 return 2216 2217 def compute_var_diffs(config, diffallvar, odir, diffscr, debug): 2218 """ Function to compute variable differences 2219 config= experiment configuration 2220 diffallvar= dictonary with the differences to compute 2221 odir= output folder 2222 diffscr= wether it should be done from the scratch 2223 """ 2224 fname = 'compute_var_diffs' 2225 2226 # output folder 2227 ofold = config['ofold'] 2228 2229 # Home of the python scripts 2230 pyH = config['pyHOME'] 2231 2232 # opsur = operation surnames 2233 opsur = gen.get_specdictionary_HMT(config, H='opsur_',M='',T='') 2234 Opsurs = {} 2235 for opk in opsur: 2236 opn = opk.split('_')[1] 2237 vals = opsur[opk] 2238 Opsurs[opn] = vals.split(':') 2239 2240 # Getting in working dir 2241 os.chdir(odir) 2242 2243 # CF dimensions 2244 CFdims = ['lon', 'lat', 'pres', 'time'] 2245 2246 # Trakcing file 2247 trkobjf = open(odir + '/all_diffvar.inf', 'a') 2248 2249 for vnop in diffallvar.keys(): 2250 vn = vnop.split('_')[0] 2251 op = vnop.split('_')[1] 2252 opSfinal = op.replace('+','_') 2253 2254 lop = op.split('+') 2255 # `p' header add related to 'pinterp' 2256 if op.find('pinterp') != -1: 2257 print warnmsg 2258 print ' ' + fname + ': there is the vertical interpolation as operation' 2259 print ' variable differences will be computed from that files where ' 2260 print ' vertical interpolation was just done' 2261 ipop = lop.index('pinterp') 2262 opS = '_' + '_'.join(lop[0:ipop+1]) 2263 doops = lop[ipop+1:] 2264 SgP = 'p' 2265 vninF = varnoper(vn, '+'.join(lop[0:ipop+1]), Opsurs) 2266 print ' operations to perform:', doops 2267 else: 2268 SgP = '' 2269 opS = '' 2270 doops = lop 2271 vninF = vn 2272 2273 Sdoops = '+'.join(doops) 2274 2275 # Variable name within the file 2276 2277 vals = diffallvar[vnop] 2278 mod1 = vals[0] 2279 mod2 = vals[1] 2280 exp1 = vals[2] 2281 exp2 = vals[3] 2282 headerf1 = vals[4] 2283 headerf2 = vals[5] 2284 modexpdiff = mod2 + '/' + exp2 + ' - ' + mod1 + '/' + exp1 2285 modexpdiffS = mod2 + '-' + exp2 + '_' + mod1 + '-' + exp1 2286 2287 ifile1 = ofold + '/' + mod1 + '/' + exp1 + '/' + vn + '_' + headerf1 + SgP + \ 2288 opS + '.nc' 2289 ifile2 = ofold + '/' + mod2 + '/' + exp2 + '/' + vn + '_' + headerf2 + SgP + \ 2290 opS + '.nc' 2291 difffilen = odir + '/' + vn + '_diffvar_' + modexpdiffS + opS + '.nc' 2292 difffinalfilen = odir + '/' + vn + '_diffvar_' + modexpdiffS + opS + '_' + \ 2293 Sdoops + '.nc' 2294 2295 if diffscr: 2296 sout = sub.call('rm ' + difffilen + ' >& /dev/null', shell=True) 2297 sout = sub.call('rm ' + difffinalfilen + ' >& /dev/null', shell=True) 2298 2299 if not os.path.isfile(difffinalfilen): 2300 if debug: 2301 print " Computing variable difference of '" + vn + "' for: '" + \ 2302 modexpdiff + "' and performing operation '" + Sdoops + "'" 2303 print " var in file: '" + vninF + "'" 2304 2305 dfiles = 'add|' + ifile2 + '|' + vninF + ',sub|' + ifile1 + '|' + vninF 2306 values = '|'.join(CFdims) + '@' + dfiles 2307 pyins = 'python ' + pyH + "/nc_var.py -o compute_opersvarsfiles -S '" + \ 2308 values + "' -v " + vninF 2309 2310 try: 2311 with gen.Capturing() as output: 2312 ncvar.compute_opersvarsfiles(values,vninF) 2313 except: 2314 print errmsg 2315 print 'ncvar.compute_opersvarsfiles(' + values + ',' + vninF + ')' 2316 for sout in output: print sout 2317 quit(-1) 2318 2319 sout = sub.call('mv opersvarsfiles_'+vninF+'.nc ' + difffilen, shell=True) 2320 2321 # keeping all differences 2322 trkobjf.write('\n') 2323 trkobjf.write("#" + vn + ' ' + op + '\n') 2324 trkobjf.write( pyins + '\n') 2325 2326 # Computing statisitcs 2327 compute_diff_statistics(config, difffilen, odir, vninF, doops, diffscr, \ 2328 debug) 2329 2330 trkobjf.close() 2331 2332 return 1810 2333 1811 2334 # Files with information about the configuration of the script … … 2005 2528 if diffscratch: 2006 2529 sub.call('rm -rf' + owdir +' >& /dev/null', shell=True) 2007 sub.call('rm ' + diff varcompf +' >& /dev/null', shell=True)2530 sub.call('rm ' + difff +' >& /dev/null', shell=True) 2008 2531 objf = open(owdir+'/all_' + fdiff,'w') 2009 2532 objf.write("## Computation and drawing of differences " + \ 2533 "between '" + exp2 + "'-'" + exp1 + "'\n") 2534 objf.close() 2535 difff = owdir + '/all_vardiffstatistics.inf' 2536 sub.call('rm ' + +' >& /dev/null', shell=True) 2537 objf = open(owdir+'/all_' + fdiff,'w') 2538 objf.write("## Computation of all differences statistics " + \ 2010 2539 "between '" + exp2 + "'-'" + exp1 + "'\n") 2011 2540 objf.close() … … 2036 2565 gen.printing_dictionary(alldiffvar) 2037 2566 2567 # Computing differences 2568 ## 2569 print " Computing operation differences ..." 2570 compute_op_diffs(cnf, alldiffop, owdir, diffscratch, dbg) 2571 print " Computing variable differences ..." 2572 compute_var_diffs(cnf, alldiffvar, owdir, diffscratch, dbg) 2573 2038 2574 quit() 2039 2575 # end of mods loop
Note: See TracChangeset
for help on using the changeset viewer.