如何修复变量未赋值即引用问题及Python代码报错排查
Fixing Issues in FITS Cube Creation Code (Unassigned Variables & Function Call Errors)
Hey Helena, let's walk through fixing your FITS cube code step by step. I spotted a few key issues that are causing errors, including unassigned variable references and logical gaps in how you're handling the data. Here's the breakdown and corrected code:
Key Issues in the Original Code
- Unassigned/Incorrectly Scoped Variables:
nonlinis calculated per file but only stores the last iteration's value. When you try to writenonlin[idx]at the end, it's a 2D array (not 3D likecube), so indexing withidxwill throw an error.- The
idx = (n>3)line inside the loop runs before all values ofnare populated, which doesn't make sense—we need to filter after collecting all data.
- Data Processing Order: You cut out the
imgslice after calculatingnonlin, butnonlinuses the full-size image. If you want the corrected non-linear data to match the cube's cutout, you need to slicenonlintoo. - Incomplete Function Call: The final
make_cubecall is missing the last parameter (y1), which will cause a positional argument error. - Global Variable Dependency: The
coeffvariable is defined outside the function, which makes the function less reusable. It's better to pass it as a parameter.
Corrected Code
from astropy.io import fits import matplotlib.pyplot as plt import numpy as np import glob import pdb # to debug # Load coefficient data first hdu_coeff = fits.open('MCtest_C1.fits') print(hdu_coeff[0].header) coeff = hdu_coeff[0].data print(f"Coefficient shape: {coeff.shape}") hdu_coeff.close() filelist = glob.glob('5/img/*.fit') # Read in all fits files def make_cube(filelist, coeff, x0, x1, y0, y1): num_files = len(filelist) exptime = np.zeros(num_files) n = np.zeros(num_files, dtype=int) # Specify int dtype since n is integer jd = np.zeros(num_files) # Initialize arrays to hold cutout data cube = None nonlin_cube = None for i, name in enumerate(filelist): with fits.open(name) as hdu: # Use context manager to auto-close files img = hdu[1].data # Calculate non-linear correction on full image first nonlin = coeff[:, :, 0] * img**3 + coeff[:, :, 1] * img**2 + coeff[:, :, 2] * img + coeff[:, :, 3] # Extract header info exptime[i] = hdu[0].header['EXPTIME'] n[i] = int(hdu[0].header['RUNSET'].split(':')[0]) jd[i] = hdu[0].header['JD'] # Apply cutout to both img and nonlin img_cut = img[x0:x1, y0:y1] nonlin_cut = nonlin[x0:x1, y0:y1] # Build cube arrays if i == 0: cube = img_cut[..., np.newaxis] # Add axis for stacking nonlin_cube = nonlin_cut[..., np.newaxis] else: cube = np.dstack((cube, img_cut)) nonlin_cube = np.dstack((nonlin_cube, nonlin_cut)) print(f"Run number: {n[i]}, Index: {i}, Cube shape: {cube.shape}") # Filter data after collecting all values idx = (n > 3) print(f"Filtered run numbers: {n[idx]}, Final cube shape: {cube[:, :, idx].shape}") # Write filtered data to FITS files # Cube hdu_cube = fits.PrimaryHDU(cube[:, :, idx]) hdu_cube.writeto(f'cube_corrected_{x0}_{x1}_{y0}_{y1}.fits', overwrite=True) # Exposure time hdu_exptime = fits.PrimaryHDU(exptime[idx]) hdu_exptime.writeto(f'exptime_corrected_{x0}_{x1}_{y0}_{y1}.fits', overwrite=True) # JD hdu_jd = fits.PrimaryHDU(jd[idx]) hdu_jd.writeto(f'jd_corrected_{x0}_{x1}_{y0}_{y1}.fits', overwrite=True) # Non-linear correction cube hdu_nonlin = fits.PrimaryHDU(nonlin_cube[:, :, idx]) hdu_nonlin.writeto(f'nonlin_corrected_{x0}_{x1}_{y0}_{y1}.fits', overwrite=True) # Complete function call with all required parameters make_cube(filelist, coeff, 0, 512, 0, 512) # Replace 512 with your actual y1 value if needed
What Changed & Why
- Pass
coeffas a Function Parameter: Makes the function self-contained instead of relying on global variables, avoiding potential scoping issues. - Initialize
nonlin_cube: We now build a 3D cube for the non-linear correction data, just like the image cube, so we can filter it properly withidx. - Fix Data Processing Order: Cut out the image and non-linear data after calculating the correction, ensuring both match the final cube dimensions.
- Use Context Manager for FITS Files:
with fits.open(name) as hduautomatically closes the file, preventing resource leaks. - Complete Function Call: Added the missing
y1parameter (set to 512 here—adjust to your actual desired slice). - Filter After Collecting All Data: Moved
idx = (n>3)to after the loop, so we filter based on all run numbers, not partial data. - Explicit Dtype for
n: Setdtype=intsincenstores integer run numbers, avoiding implicit type conversion issues.
内容的提问来源于stack exchange,提问作者helena
相关产品推荐
相关产品推荐

