1 | ############################################################ |
---|
2 | ### Python script to analyse a NetCDF file for debugging ### |
---|
3 | ############################################################ |
---|
4 | |
---|
5 | ### This script gives useful information about a NetCDF file |
---|
6 | ### to help for debugging. For each variable, it outputs the |
---|
7 | ### dimensions, the min & max values, the average value and |
---|
8 | ### warns the user in case of NaN or negative values. |
---|
9 | ### The file name is asked to the user in the terminal. |
---|
10 | |
---|
11 | import os |
---|
12 | import readline |
---|
13 | import glob |
---|
14 | from netCDF4 import Dataset |
---|
15 | import numpy as np |
---|
16 | |
---|
17 | ############################################################ |
---|
18 | ### Setup readline for file name autocompletion |
---|
19 | def complete(text,state): |
---|
20 | line = readline.get_line_buffer().split() |
---|
21 | # Use glob to find all matching files/directories for the current text |
---|
22 | if '*' not in text: |
---|
23 | text += '*' |
---|
24 | matches = glob.glob(os.path.expanduser(text)) |
---|
25 | # Add '/' if the match is a directory |
---|
26 | matches = [match + '/' if os.path.isdir(match) else match for match in matches] |
---|
27 | |
---|
28 | try: |
---|
29 | return matches[state] |
---|
30 | except IndexError: |
---|
31 | return None |
---|
32 | |
---|
33 | ### Function to analyze a variable in a NetCDF file |
---|
34 | def analyze_variable(variable): |
---|
35 | # Get the data for the variable |
---|
36 | data = variable[:] |
---|
37 | |
---|
38 | # Calculate min, max and mean |
---|
39 | if np.isnan(data).all(): |
---|
40 | min_val = np.nan |
---|
41 | max_val = np.nan |
---|
42 | mean_val = np.nan |
---|
43 | else: |
---|
44 | data_min = np.nanmin(data) # Min value ignoring NaN |
---|
45 | data_max = np.nanmax(data) # Max value ignoring NaN |
---|
46 | data_mean = np.nanmean(data) # Mean value ignoring NaN |
---|
47 | |
---|
48 | # Check if there are any NaN values |
---|
49 | has_nan = np.isnan(data).any() |
---|
50 | |
---|
51 | # Check for negative values |
---|
52 | has_negative = (data < 0).any() |
---|
53 | |
---|
54 | # Print the results |
---|
55 | print(f"\nAnalysis of variable: {variable.name}") |
---|
56 | print(f" Dimensions: {variable.dimensions}") |
---|
57 | print(f" Min value : {data_min:>12.6e}") |
---|
58 | print(f" Max value : {data_max:>12.6e}") |
---|
59 | print(f" Mean value: {data_mean:>12.6e}") |
---|
60 | if has_nan: |
---|
61 | print(f" \033[91mContains NaN values!\033[0m") |
---|
62 | if has_negative: |
---|
63 | print(f" \033[93mWarning: contains negative values!\033[0m") |
---|
64 | |
---|
65 | ### Main function |
---|
66 | def analyze_netcdf(): |
---|
67 | # Ask for the file name |
---|
68 | readline.set_completer(complete) |
---|
69 | readline.parse_and_bind('tab: complete') |
---|
70 | file = input("Enter the name of the NetCDF file: ") |
---|
71 | |
---|
72 | # Open the NetCDF file |
---|
73 | try: |
---|
74 | dataset = Dataset(file,mode='r') |
---|
75 | except FileNotFoundError: |
---|
76 | print(f"File '{file}' not found.") |
---|
77 | return |
---|
78 | |
---|
79 | # Iterate through all variables in the dataset to analyze them |
---|
80 | for variable_name in dataset.variables: |
---|
81 | variable = dataset.variables[variable_name] |
---|
82 | analyze_variable(variable) |
---|
83 | |
---|
84 | # Close the NetCDF file |
---|
85 | dataset.close() |
---|
86 | |
---|
87 | ### Call the main function |
---|
88 | analyze_netcdf() |
---|
89 | |
---|