File size: 7,590 Bytes
2df9cf5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
#!/usr/bin/env python3
"""
Integration script to handle Arctic GRIB files in your wave puller
Automatically detects polar stereographic errors and uses alternative extraction
"""

import os
import sys
import tempfile
import pandas as pd
from pathlib import Path

# Import our Arctic extractor
from arctic_grib_extractor import ArcticGRIBExtractor

def process_arctic_grib_safe(grib_file, output_format='dataframe'):
    """
    Safe processing of Arctic GRIB files that bypasses ECCODES polar stereographic errors
    
    Args:
        grib_file (str): Path to Arctic GRIB file
        output_format (str): 'dataframe', 'csv', or 'netcdf'
    
    Returns:
        pandas.DataFrame or str: Extracted data or path to saved file
    """
    print(f"🌊 Processing Arctic GRIB file: {grib_file}")
    
    if not os.path.exists(grib_file):
        raise FileNotFoundError(f"GRIB file not found: {grib_file}")
    
    # Create extractor
    extractor = ArcticGRIBExtractor()
    
    # Extract data using all available methods
    data, method = extractor.extract_all_methods(grib_file)
    
    if data is None:
        raise RuntimeError("Failed to extract data from Arctic GRIB file using all methods")
    
    print(f"βœ… Successfully extracted {len(data)} points using {method}")
    
    # Return based on requested format
    if output_format == 'dataframe':
        return data
    
    elif output_format == 'csv':
        csv_file = grib_file.replace('.grib2', '_extracted.csv')
        data.to_csv(csv_file, index=False)
        print(f"πŸ’Ύ Saved to CSV: {csv_file}")
        return csv_file
    
    elif output_format == 'netcdf':
        try:
            import xarray as xr
            
            # Convert to xarray and save
            if 'latitude' in data.columns and 'longitude' in data.columns:
                val_col = 'value' if 'value' in data.columns else 'val'
                
                ds = xr.Dataset({
                    'wave_data': (['point'], data[val_col]),
                    'latitude': (['point'], data['latitude']),
                    'longitude': (['point'], data['longitude'])
                })
                
                ds.attrs['extraction_method'] = method
                ds.attrs['source_file'] = grib_file
                
                nc_file = grib_file.replace('.grib2', '_extracted.nc')
                ds.to_netcdf(nc_file)
                print(f"πŸ’Ύ Saved to NetCDF: {nc_file}")
                return nc_file
            else:
                # Fall back to CSV
                return process_arctic_grib_safe(grib_file, 'csv')
                
        except ImportError:
            print("⚠️ xarray not available, falling back to CSV")
            return process_arctic_grib_safe(grib_file, 'csv')
    
    else:
        raise ValueError(f"Unknown output format: {output_format}")

def arctic_grib_handler(grib_file_path):
    """
    Drop-in replacement for problematic Arctic GRIB processing
    Use this function when you encounter ECCODES polar stereographic errors
    """
    try:
        # First, try your normal processing
        # If it fails with polar stereographic error, use this
        
        print("πŸ”„ Attempting Arctic GRIB extraction due to ECCODES error...")
        
        # Extract all data points
        df = process_arctic_grib_safe(grib_file_path, 'dataframe')
        
        # Convert to the format your application expects
        result = {
            'coordinates': df[['latitude', 'longitude']].values.tolist(),
            'data': df['value'].values.tolist() if 'value' in df.columns else df['val'].values.tolist(),
            'total_points': len(df),
            'lat_range': [df['latitude'].min(), df['latitude'].max()],
            'lon_range': [df['longitude'].min(), df['longitude'].max()],
            'extraction_method': 'arctic_bypass'
        }
        
        return result
        
    except Exception as e:
        print(f"❌ Arctic GRIB handler failed: {e}")
        raise

def integrate_with_wave_puller():
    """
    Example integration with your existing wave puller
    """
    
    # Example of how to modify your existing code
    sample_code = '''
    # In your grib_wave_puller, replace the problematic Arctic processing with:
    
    def process_arctic_region(grib_file):
        """Modified Arctic processing that handles polar stereographic errors"""
        try:
            # Your original processing code here
            # ... existing Arctic processing ...
            
        except Exception as e:
            if "Polar stereographic" in str(e) or "spherical earth" in str(e):
                print("ECCODES polar stereographic error detected, using alternative extraction...")
                
                # Use our Arctic handler
                from arctic_integration import arctic_grib_handler
                result = arctic_grib_handler(grib_file)
                
                print(f"Extracted {result['total_points']} Arctic data points")
                return result
            else:
                raise  # Re-raise if it's a different error
    '''
    
    print("Integration example:")
    print(sample_code)

def batch_process_arctic_files(grib_directory, output_directory=None):
    """
    Batch process multiple Arctic GRIB files
    """
    if output_directory is None:
        output_directory = grib_directory
    
    grib_files = list(Path(grib_directory).glob("*.grib2"))
    print(f"Found {len(grib_files)} GRIB files to process")
    
    results = []
    
    for grib_file in grib_files:
        print(f"\nπŸ“ Processing: {grib_file.name}")
        
        try:
            output_file = os.path.join(output_directory, f"{grib_file.stem}_extracted.csv")
            csv_file = process_arctic_grib_safe(str(grib_file), 'csv')
            
            # Move to output directory if different
            if output_directory != grib_directory:
                import shutil
                shutil.move(csv_file, output_file)
                csv_file = output_file
            
            results.append({
                'source': str(grib_file),
                'output': csv_file,
                'status': 'success'
            })
            
        except Exception as e:
            print(f"❌ Failed to process {grib_file.name}: {e}")
            results.append({
                'source': str(grib_file),
                'output': None,
                'status': 'failed',
                'error': str(e)
            })
    
    # Summary
    successful = sum(1 for r in results if r['status'] == 'success')
    print(f"\nπŸ“Š Batch processing complete:")
    print(f"  βœ… Successful: {successful}")
    print(f"  ❌ Failed: {len(results) - successful}")
    
    return results

if __name__ == "__main__":
    # Command line usage
    if len(sys.argv) > 1:
        grib_file = sys.argv[1]
        output_format = sys.argv[2] if len(sys.argv) > 2 else 'csv'
        
        try:
            result = process_arctic_grib_safe(grib_file, output_format)
            print(f"πŸŽ‰ Success! Result: {result}")
        except Exception as e:
            print(f"❌ Error: {e}")
            sys.exit(1)
    else:
        print("Usage:")
        print("  python arctic_integration.py <grib_file> [output_format]")
        print("  output_format: 'dataframe', 'csv', or 'netcdf'")
        print("")
        print("Example:")
        print("  python arctic_integration.py /tmp/tmp0cvj_act.grib2 csv")
        
        # Show integration example
        integrate_with_wave_puller()