redgrid_series.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #!/usr/bin/env python
  2. import sys
  3. import math
  4. import numpy as np
  5. #import pdb
  6. """
  7. Return lits with possible "ncomb" that can be used together to define reduced
  8. grid, according to input resolution.
  9. 13 Jun 2013 - Ph. Le Sager - v0
  10. """
  11. # ------- Err
  12. def wrong_input(mess):
  13. print mess
  14. print("Usage: %s RESOLUTION_LONG RESOLUTION_LAT" % sys.argv[0])
  15. return
  16. # -------
  17. def replace_multi(mylist, reflist):
  18. """
  19. Return lists formed with input list + results of
  20. find_multiple applied to last element of input list
  21. (Recursive)
  22. """
  23. val=mylist[-1]
  24. a=reflist.index(val)
  25. zelists=[]
  26. b=[f for f in reflist[a+1:] if not f%val] # find_multiple
  27. for i,j in enumerate(b):
  28. # skip some (they would be subset of another)
  29. check=[k for k in b[:i] if j%k==0]
  30. if check: continue
  31. c=mylist[:]
  32. c.append(j)
  33. newlists=replace_multi(c,reflist)
  34. if newlists:
  35. for k in newlists: zelists.append(k)
  36. else:
  37. zelists.append(c)
  38. return zelists
  39. # ------- Input
  40. total = len(sys.argv)
  41. if total < 3 :
  42. dummy=wrong_input("Two arguments required!")
  43. sys.exit(1)
  44. resolution=float(sys.argv[1])
  45. # May need different check for some non-integer resolution (1/3 for example):
  46. if 360.%resolution:
  47. dummy=wrong_input("Argument must divide 360!")
  48. sys.exit(1)
  49. nbox=int(360/resolution)
  50. print ""
  51. print "Resolution = %s" % resolution
  52. print "Nb of boxes = %s" % nbox
  53. # ------- Possible sequences of multiples
  54. divisors=[f for f in range(2,nbox+1) if not nbox%f] # List of divisors
  55. alllists=[]
  56. for i in range(len(divisors)):
  57. l=divisors[i:i+1]
  58. # limit to "prime number" in the list
  59. cl=[k for k in divisors[0:i] if not l[0]%k]
  60. if cl: continue
  61. newlists=replace_multi(l, divisors)
  62. for k in newlists: alllists.append(k)
  63. if alllists:
  64. print """
  65. You can use any of the following %s sequences (or any subset of them) to
  66. define a ReducedGrid. But you cannot mix these sequences.
  67. """ % len(alllists)
  68. for k in alllists: print k
  69. # ------- Choice and corresponding grid size
  70. Re=6371. # Earth radius in km
  71. pi=math.pi
  72. lat_res=float(sys.argv[2])
  73. choice=raw_input("""
  74. Enter comma-separated list of 'ncomb', starting from pole.
  75. (for example: 40,8,8,4,4,4,2). Leave empty to exit.
  76. > """)
  77. if choice == '' : sys.exit(0)
  78. choice=choice.split(',')
  79. choice=np.array(choice,dtype=int)
  80. nbands=len(choice)
  81. lats=90.-(np.arange(nbands)+0.5)*lat_res # at center of the grid boxes
  82. ndx = 2*pi*Re*np.cos(lats*pi/180.)*choice/nbox # box width in km
  83. odx = 2*pi*Re*np.cos(lats*pi/180.)/nbox # old box width in km
  84. print ""
  85. print " band #".rjust(8), "Lat.".rjust(7), "Old Width, New Width [km]"
  86. for i,k in enumerate(ndx):
  87. print repr(i).rjust(8), ' {0:6.2f}'.format(lats[i]), \
  88. '{0:9.1f}'.format(odx[i]), '{0:10.1f}'.format(k)