modis_check.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #!/usr/bin/env python
  2. # script to check which tiles are missing
  3. #
  4. # (c) Copyright Luca Delucchi 2018
  5. # Authors: Luca Delucchi
  6. # Email: luca dot delucchi at fmach dot it
  7. #
  8. ##################################################################
  9. #
  10. # This MODIS Python script is licensed under the terms of GNU GPL 2.
  11. # This program is free software; you can redistribute it and/or
  12. # modify it under the terms of the GNU General Public License as
  13. # published by the Free Software Foundation; either version 2 of
  14. # the License, or (at your option) any later version.
  15. # This program is distributed in the hope that it will be useful,
  16. # but WITHOUT ANY WARRANTY; without even implied warranty of
  17. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  18. # See the GNU General Public License for more details.
  19. #
  20. ##################################################################
  21. """script to check which tiles are missing"""
  22. import glob
  23. import os
  24. import sys
  25. import calendar
  26. import copy
  27. from datetime import datetime
  28. from collections import OrderedDict
  29. try:
  30. from pymodis import optparse_gui
  31. WXPYTHON = True
  32. except:
  33. WXPYTHON = False
  34. from pymodis import optparse_required
  35. def main():
  36. """Main function"""
  37. # usage
  38. usage = "usage: %prog [options] destination_folder"
  39. if 1 == len(sys.argv) and WXPYTHON:
  40. option_parser_class = optparse_gui.OptionParser
  41. else:
  42. option_parser_class = optparse_required.OptionParser
  43. parser = option_parser_class(usage=usage, description='modis_check')
  44. # output
  45. parser.add_option("-o", "--outputs", dest="outs", default="stdout",
  46. help="the output where write "
  47. "[default=%default]")
  48. # tiles
  49. parser.add_option("-t", "--tiles", dest="tiles", default=None,
  50. help="string of tiles separated with comma "
  51. "[default=%default for all tiles]")
  52. # the product
  53. parser.add_option("-p", "--product", dest="prod", default="MOD11A1",
  54. help="product name as on the http/ftp server "
  55. "[default=%default]")
  56. # the MODIS version
  57. parser.add_option("-m", "--modis_version", dest="mver", default="006",
  58. help="the version of MODIS product "
  59. "[default=%default]")
  60. # first day
  61. parser.add_option("-f", "--firstday", dest="today", default=None,
  62. help="the day to start download [default=%default is for"
  63. " today]; if you want change data you must use "
  64. "this format YYYY-MM-DD", metavar="FIRST_DAY")
  65. # last day
  66. parser.add_option("-e", "--endday", dest="enday", default=None,
  67. metavar="LAST_DAY", help="the day to stop download "
  68. "[default=%default]; if you want change"
  69. " data you must use this format YYYY-MM-DD")
  70. # number of days
  71. parser.add_option("-d", "--days", dest="days", default=1, metavar="DAYS",
  72. help="The temporal resolution of the dataset, "
  73. "[default=%default]")
  74. # return options and argument
  75. (options, args) = parser.parse_args()
  76. # test if args[0] it is set
  77. if len(args) == 0 and not WXPYTHON:
  78. parser.print_help()
  79. sys.exit(1)
  80. if len(args) == 0:
  81. parser.error("You have to define the destination folder for HDF file")
  82. if not os.path.isdir(args[0]):
  83. parser.error("The destination folder is not a dir or not exists")
  84. sday = 1
  85. if options.today:
  86. sday = int(datetime.strptime(options.today, "%Y-%m-%d").strftime("%j"))
  87. eday = 366
  88. if options.enday:
  89. eday = int(datetime.strptime(options.enday, "%Y-%m-%d").strftime("%j"))
  90. tres = int(options.days)
  91. if options.outs == "stdout":
  92. write = sys.stdout
  93. else:
  94. write = open(options.outs, 'w')
  95. files = glob.glob(os.path.join(args[0], '*.hdf'))
  96. tiles = options.tiles.split(',')
  97. output = OrderedDict()
  98. missing_dates = {}
  99. for fi in files:
  100. if fi.startswith('./'):
  101. fi = fi.lstrip('./')
  102. if fi.count('.') != 5:
  103. print("Error with file {fi}, to many dots, skipping it. Please " \
  104. "to be sure run it for the same folder containing the HDF" \
  105. " file".format(fi=fi))
  106. continue
  107. fisplit = fi.split('.')
  108. dat = fisplit[1]
  109. year = int(dat[1:5])
  110. if year not in missing_dates.keys():
  111. if eday == 366 and calendar.isleap(year):
  112. eday = 367
  113. missing_dates[year] = list(range(sday, eday, tres))
  114. doy = int(dat[5:8])
  115. try:
  116. missing_dates[year].remove(doy)
  117. except ValueError:
  118. pass
  119. if dat not in output.keys():
  120. output[dat] = copy.deepcopy(tiles)
  121. try:
  122. output[dat].remove(fisplit[2])
  123. except ValueError:
  124. continue
  125. for k, v in missing_dates.items():
  126. for dat in v:
  127. for ti in tiles:
  128. yd = "A{ye}{do}".format(ye=k, do=str(dat).zfill(3))
  129. write.write("{co}\n".format(co=".".join((options.prod, yd, ti,
  130. options.mver, '*',
  131. 'hdf*'))))
  132. for k, v in output.items():
  133. if len(v) != 0:
  134. for ti in v:
  135. write.write("{co}\n".format(co=".".join((options.prod, k,
  136. ti, options.mver,
  137. '*', 'hdf*'))))
  138. if options.outs != "stdout":
  139. write.close()
  140. if __name__ == "__main__":
  141. main()