Skip to content

Commit da05433

Browse files
committed
improved MarsPull readability
1 parent e876f2b commit da05433

File tree

3 files changed

+125
-71
lines changed

3 files changed

+125
-71
lines changed

bin/MarsFormat.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
and maintained by the Mars Climate Modeling Center (MCMC). The MGCM
77
data repository is available at data.nas.nasa.gov/mcmc.
88
9-
The executable requires 2 arguments:
9+
The executable requires two arguments:
1010
1111
* ``[input_file]`` The file to be transformed
1212
* ``[-gcm --gcm_name]`` The GCM from which the file originates
@@ -17,7 +17,7 @@
1717
* ``[-ba, --bin_average]`` Bin non-MGCM files like 'average' files
1818
* ``[-bd, --bin_diurn]`` Bin non-MGCM files like 'diurn' files
1919
20-
Third-party Requirements:
20+
Third-party requirements:
2121
2222
* ``numpy``
2323
* ``netCDF4``

bin/MarsPlot.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,31 @@
7171
global current_version
7272
current_version = 3.5
7373

74+
import functools
75+
import traceback
76+
77+
def debug_wrapper(func):
78+
"""
79+
A decorator that wraps a function with error handling based on the
80+
--debug flag.
81+
"""
82+
@functools.wraps(func)
83+
def wrapper(*args, **kwargs):
84+
global debug
85+
try:
86+
return func(*args, **kwargs)
87+
except Exception as e:
88+
if debug:
89+
# In debug mode, show the full traceback
90+
print(f"{Red}ERROR in {func.__name__}: {str(e)}{Nclr}")
91+
traceback.print_exc()
92+
else:
93+
# In normal mode, show a clean error message
94+
print(f"{Red}ERROR in {func.__name__}: {str(e)}\nUse "
95+
f"--debug for more information.{Nclr}")
96+
return 1 # Error exit code
97+
return wrapper
98+
7499
# ======================================================
75100
# ARGUMENT PARSER
76101
# ======================================================
@@ -309,6 +334,7 @@
309334
# ======================================================================
310335
# MAIN PROGRAM
311336
# ======================================================================
337+
@debug_wrapper
312338
def main():
313339
global output_path, input_paths, out_format, debug
314340
output_path = os.getcwd()
@@ -4336,4 +4362,5 @@ def do_plot(self):
43364362
# ======================================================================
43374363

43384364
if __name__ == "__main__":
4339-
main()
4365+
exit_code = main()
4366+
sys.exit(exit_code)

bin/MarsPull.py

Lines changed: 95 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ def wrapper(*args, **kwargs):
147147
# ======================================================
148148

149149

150-
saveDir = (f"{os.getcwd()}/")
150+
save_dir = (f"{os.getcwd()}/")
151151

152152
# available files by Ls:
153153
Ls_ini = np.array([
@@ -166,52 +166,54 @@ def wrapper(*args, **kwargs):
166166
310, 316, 321, 327, 333, 338, 344, 349, 354, 0
167167
])
168168

169-
170-
171-
def download(url, filename):
169+
def download(url, file_name):
172170
"""
173171
Downloads a file from the NAS Data Portal (data.nas.nasa.gov).
174172
175-
:param url: The url to download, e.g 'https://data.nas.nasa.gov/legacygcm/download_data.php?file=/legacygcmdata/LegacyGCM_Ls000_Ls004.nc'
173+
:param url: The url to download from, e.g 'https://data.nas.nasa.\
174+
gov/legacygcm/download_data.php?file=/legacygcmdata/LegacyGCM_\
175+
Ls000_Ls004.nc'
176176
:type url: str
177177
178-
:param filename: The local filename e.g '/lou/la4/akling/Data/LegacyGCM_Ls000_Ls004.nc'
179-
:type filename: str
178+
:param file_name: The local file_name e.g '/lou/la4/akling/Data/L\
179+
egacyGCM_Ls000_Ls004.nc'
180+
:type file_name: str
180181
181-
:return: The requested file(s), downloaded and saved to the current \
182-
directory.
182+
:return: The requested file(s), downloaded and saved to the \
183+
current directory.
183184
184185
:raises FileNotFoundError: A file-not-found error.
185186
186187
"""
187188

188-
_ , fname=os.path.split(filename)
189+
_, fname = os.path.split(file_name)
189190
response = requests.get(url, stream=True)
190191
total = response.headers.get('content-length')
191192

192193
if response.status_code == 404:
193-
print('Error during download, error code is: ',response.status_code)
194+
print(f'Error during download, error code is: {response.status_code}')
194195
else:
195-
196-
#If we have access to the size of the file, return progress bar
197196
if total is not None:
198-
with open(filename, 'wb') as f:
197+
# If file size is known, return progress bar
198+
with open(file_name, 'wb') as f:
199199
downloaded = 0
200-
if total :total = int(total)
201-
for data in response.iter_content(chunk_size=max(int(total/1000), 1024*1024)):
200+
if total:
201+
total = int(total)
202+
for data in response.iter_content(
203+
chunk_size = max(int(total/1000), 1024*1024)
204+
):
202205
downloaded += len(data)
203206
f.write(data)
204207
status = int(50*downloaded/total)
205-
sys.stdout.write(f"\r[{'#'*status}{'.'*(50-status)}]")
208+
sys.stdout.write(f"\r[{'#'*status}{'.'*(50 - status)}]")
206209
sys.stdout.flush()
207210
sys.stdout.write('\n')
208211
else:
209-
210-
#Header is unknown yet, skip the use of a progress bar
211-
print('Downloading %s ...'%(fname))
212-
with open(filename, 'wb')as f:
212+
# If file size is unknown, skip progress bar
213+
print(f"Downloading {fname}...")
214+
with open(file_name, 'wb')as f:
213215
f.write(response.content)
214-
print('%s Done'%(fname))
216+
print(f"{fname} Done")
215217

216218
def file_list(list_of_files):
217219
print("Available files:")
@@ -231,18 +233,26 @@ def main():
231233

232234
if args.list_files:
233235
# Send an HTTP GET request to the URL and store the response.
234-
legacy_data = requests.get('https://data.nas.nasa.gov/mcmcref/legacygcm/')
235-
fv3_data = requests.get('https://data.nas.nasa.gov/mcmcref/fv3betaout1/')
236+
legacy_data = requests.get(
237+
'https://data.nas.nasa.gov/mcmcref/legacygcm/'
238+
)
239+
fv3_data = requests.get(
240+
'https://data.nas.nasa.gov/mcmcref/fv3betaout1/'
241+
)
236242

237-
# Access the text content of the response, which contains the webpage's HTML.
243+
# Access the text content of the response, which contains the
244+
# webpage's HTML.
238245
legacy_dir_text = legacy_data.text
239246
fv3_dir_text = fv3_data.text
240247

241248
# Search for the URLs beginning with the below string
242-
legacy_dir_search = "https://data\.nas\.nasa\.gov/legacygcm/legacygcmdata/"
249+
legacy_dir_search = (
250+
"https://data\.nas\.nasa\.gov/legacygcm/legacygcmdata/"
251+
)
243252

244253
legacy_urls = re.findall(
245-
fr"{legacy_dir_search}[a-zA-Z0-9_\-\.~:/?#\[\]@!$&'()*+,;=]+", legacy_dir_text
254+
fr"{legacy_dir_search}[a-zA-Z0-9_\-\.~:/?#\[\]@!$&'()*+,;=]+",
255+
legacy_dir_text
246256
)
247257

248258
print("Available directories:")
@@ -253,65 +263,82 @@ def main():
253263
legacy_data = requests.get(legacy_urls[0])
254264
legacy_dir_text = legacy_data.text
255265

256-
legacy_files_available = re.findall(r'download="(fort\.11_[0-9]+)"', legacy_dir_text)
257-
fv3_files_available = re.findall(r'href="[^"]*\/([^"\/]+\.nc)"', fv3_dir_text)
258-
266+
legacy_files_available = re.findall(r'download="(fort\.11_[0-9]+)"',
267+
legacy_dir_text)
268+
fv3_files_available = re.findall(r'href="[^"]*\/([^"\/]+\.nc)"',
269+
fv3_dir_text)
259270

260271
file_list(legacy_files_available)
261272
file_list(fv3_files_available)
262273

263274
if args.directory_name:
264275
portal_dir=args.directory_name
265-
if portal_dir in ['ACTIVECLDS', 'INERTCLDS', 'NEWBASE_ACTIVECLDS', 'ACTIVECLDS_NCDF']:
266-
url_requested="https://data.nas.nasa.gov/legacygcm/legacygcmdata/"+portal_dir+'/'
276+
if portal_dir in [
277+
'ACTIVECLDS', 'INERTCLDS', 'NEWBASE_ACTIVECLDS', 'ACTIVECLDS_NCDF'
278+
]:
279+
requested_url = (
280+
"https://data.nas.nasa.gov/legacygcm/legacygcmdata/"
281+
+ portal_dir
282+
+ "/"
283+
)
267284
elif portal_dir in ['FV3BETAOUT1']:
268-
url_requested="https://data.nas.nasa.gov/legacygcm/fv3betaout1data/"
285+
requested_url = (
286+
"https://data.nas.nasa.gov/legacygcm/fv3betaout1data/"
287+
)
269288

270289
if not (args.ls or args.filename):
271290
prYellow("ERROR No file requested. Use [-ls --ls] or "
272291
"[-f --filename] to specify a file to download.")
273-
sys.exit(1) # Use sys.exit(1) to return a non-zero exit code
292+
sys.exit(1) # Return a non-zero exit code
293+
294+
if args.ls:
295+
data_input = np.asarray(args.ls)
296+
if len(data_input) == 1:
297+
# Query the file that contains this Ls
298+
closest_index = np.argmin(np.abs(Ls_ini - data_input))
299+
if data_input < Ls_ini[closest_index]:
300+
closest_index -= 1
301+
file_list = np.arange(closest_index, closest_index + 1)
302+
303+
elif len(data_input) == 2:
304+
# Query files within this range of Ls
305+
i_start = np.argmin(np.abs(Ls_ini - data_input[0]))
306+
if data_input[0] < Ls_ini[i_start]:
307+
i_start -= 1
308+
309+
i_end = np.argmin(np.abs(Ls_end - data_input[1]))
310+
if data_input[1] > Ls_end[i_end]:
311+
i_end += 1
312+
313+
file_list = np.arange(i_start, i_end + 1)
314+
315+
prCyan(f"Saving {len(file_list)} file(s) to {save_dir}")
274316

275-
if args.ls :
276-
data_input=np.asarray(args.ls)
277-
if len(data_input)==1: #query only the file that contains this Ls
278-
i_start=np.argmin(np.abs(Ls_ini-data_input))
279-
if data_input<Ls_ini[i_start]:i_start-=1
280-
num_files=np.arange(i_start,i_start+1)
281-
282-
elif len(data_input)==2: #start stop is provided
283-
i_start=np.argmin(np.abs(Ls_ini-data_input[0]))
284-
if data_input[0]<Ls_ini[i_start]:i_start-=1
285-
286-
i_end=np.argmin(np.abs(Ls_end-data_input[1]))
287-
if data_input[1]>Ls_end[i_end]:i_end+=1
288-
289-
num_files=np.arange(i_start,i_end+1)
290-
prCyan(f"Saving {len(num_files)} file(s) to {saveDir}")
291-
for ii in num_files:
292-
#Legacy .nc files
293-
if portal_dir=='ACTIVECLDS_NCDF':
294-
file_name='LegacyGCM_Ls%03d_Ls%03d.nc'%(Ls_ini[ii],Ls_end[ii])
295-
#fort.11 files
317+
for ii in file_list:
318+
if portal_dir == 'ACTIVECLDS_NCDF':
319+
# Legacy .nc files
320+
file_name = (
321+
f"LegacyGCM_Ls{Ls_ini[ii]:03d}_Ls{Ls_end[ii]:03d}.nc"
322+
)
296323
else:
297-
file_name='fort.11_%04d'%(670+ii)
324+
# fort.11 files
325+
file_name = f"fort.11_{670+ii:04d}"
298326

299-
url = url_requested+file_name
300-
filename=saveDir+file_name
301-
#print('Downloading '+ file_name+ '...')
302-
print('Downloading '+ url+ '...')
303-
download(url,filename)
327+
url = requested_url + file_name
328+
file_name = save_dir + file_name
329+
print(f"Downloading {url}...")
330+
download(url, file_name)
304331

305332
elif args.filename:
306-
f_input=np.asarray(args.filename)
307-
for ff in f_input :
308-
url = url_requested+ff
309-
filename=saveDir+ff
310-
print('Downloading '+ url+ '...')#ff
311-
download(url,filename)
333+
requested_files = np.asarray(args.filename)
334+
for f in requested_files:
335+
url = requested_url + f
336+
file_name = save_dir + f
337+
print(f"Downloading {url}...")
338+
download(url, file_name)
312339

313340
elif not args.list_files:
314-
# If no directory is provided and it's not a list files request
341+
# If no directory is provided and its not a -list request
315342
prYellow("ERROR: A directory must be specified unless using -list.")
316343
sys.exit(1)
317344

0 commit comments

Comments
 (0)