-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added support for stacked images #392
Changes from all commits
4489497
00dd08a
c43dec3
2c563af
d8aea06
305638c
05d66b6
7ae8bc2
f2ef342
856c8ba
4f3776a
5c679ba
38da0e0
ba54178
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,8 @@ def calibration_type(self): | |
return 'BIAS' | ||
|
||
def make_master_calibration_frame(self, images): | ||
for image in images: | ||
image /= image.n_sub_exposures | ||
master_image = super(BiasMaker, self).make_master_calibration_frame(images) | ||
master_image.bias_level = np.mean([image.bias_level for image in images if image.bias_level is not None]) | ||
return master_image | ||
|
@@ -31,9 +33,9 @@ def calibration_type(self): | |
return 'bias' | ||
|
||
def apply_master_calibration(self, image, master_calibration_image): | ||
image -= master_calibration_image.bias_level | ||
image -= master_calibration_image.bias_level * image.n_sub_exposures | ||
image.meta['BIASLVL'] = master_calibration_image.bias_level, 'Bias level that was removed after overscan' | ||
image -= master_calibration_image | ||
image -= master_calibration_image * image.n_sub_exposures | ||
image.meta['L1IDBIAS'] = master_calibration_image.filename, 'ID of bias frame' | ||
image.meta['L1STATBI'] = 1, "Status flag for bias frame correction" | ||
return image | ||
|
@@ -65,7 +67,9 @@ def __init__(self, runtime_context): | |
def do_stage(self, image): | ||
bias_level = stats.sigma_clipped_mean(image.data, 3.5, mask=image.mask) | ||
image -= bias_level | ||
image.meta['BIASLVL'] = bias_level, 'Bias level that was removed after overscan' | ||
# This is only run for bias frames and n_sub_exposures should always be 1 | ||
# but we divide it here for consistency to cover pathological uses cases | ||
image.meta['BIASLVL'] = bias_level / image.n_sub_exposures, 'Bias level that was removed after overscan' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. here is is divided by the image.n_sub_exposure |
||
return image | ||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -132,7 +132,8 @@ def __init__(self, data: Union[np.array, Table], meta: fits.Header, | |
mask: np.array = None, name: str = '', uncertainty: np.array = None, memmap=True): | ||
super().__init__(data=data, meta=meta, mask=mask, name=name, memmap=memmap) | ||
if uncertainty is None: | ||
uncertainty = self.read_noise * np.ones(data.shape, dtype=data.dtype) / self.gain | ||
uncertainty = self.read_noise * np.sqrt(self.n_sub_exposures) * np.ones(data.shape, dtype=data.dtype) | ||
uncertainty /= self.gain | ||
self.uncertainty = self._init_array(uncertainty) | ||
self._detector_section = Section.parse_region_keyword(self.meta.get('DETSEC')) | ||
self._data_section = Section.parse_region_keyword(self.meta.get('DATASEC')) | ||
|
@@ -155,6 +156,15 @@ def __imul__(self, value): | |
self.meta['MAXLIN'] *= value | ||
return self | ||
|
||
def __mul__(self, value): | ||
output = CCDData(self.data * value, meta=self.meta.copy(), | ||
name=self.name, uncertainty=self.uncertainty * value, | ||
mask=self.mask.copy(), memmap=self.memmap) | ||
output.meta['SATURATE'] *= value | ||
output.meta['GAIN'] /= value | ||
output.meta['MAXLIN'] *= value | ||
return output | ||
|
||
def __itruediv__(self, value): | ||
if isinstance(value, CCDData): | ||
self.uncertainty = np.abs(self.data / value.data) * \ | ||
|
@@ -176,7 +186,7 @@ def to_fits(self, context): | |
|
||
def __del__(self): | ||
super().__del__() | ||
del self.uncertainty | ||
del self._uncertainty | ||
|
||
def __isub__(self, value): | ||
if isinstance(value, CCDData): | ||
|
@@ -192,9 +202,14 @@ def __sub__(self, other): | |
return type(self)(data=self.data - other.data, meta=self.meta, mask=self.mask | other.mask, | ||
uncertainty=uncertainty) | ||
|
||
def add_uncertainty(self, readnoise: np.array): | ||
self._validate_array(readnoise) | ||
self.uncertainty = self._init_array(readnoise) | ||
@property | ||
def uncertainty(self): | ||
return self._uncertainty | ||
|
||
@uncertainty.setter | ||
def uncertainty(self, value: np.array): | ||
self._validate_array(value) | ||
self._uncertainty = self._init_array(value) | ||
|
||
def signal_to_noise(self): | ||
return np.abs(self.data) / self.uncertainty | ||
|
@@ -302,6 +317,17 @@ def data_section(self, section): | |
self.meta['DATASEC'] = section.to_region_keyword() | ||
self._data_section = section | ||
|
||
@property | ||
def n_sub_exposures(self): | ||
n_exposures = self.meta.get('NSUBREAD', 1) | ||
if str(n_exposures).lower() in ['n/a', 'unknown', 'none', '']: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure what the full list of possible There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good idea to put a float in like 1.5 - now what? Shoudl be a reject for invalid value There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right now, if there is something pathological in the data like nsubread=1.5, we will crash out and raise an error which I think is the right behavior. The cases here are the ones we assume we are ok and can safely treat things as 1 subread. |
||
n_exposures = 1 | ||
return n_exposures | ||
|
||
@n_sub_exposures.setter | ||
def n_sub_exposures(self, value): | ||
self.meta['NSUBREAD'] = value | ||
|
||
def rebin(self, binning): | ||
# TODO: Implement me | ||
return self | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the BIASLVL header be changed to reflect the multiplicative factor of n_sub_exposures?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, regardless of n_sub_exposures why are we subtracting both bias.level and bias.image, where in line 19, amke_master_calibration, master_iamge is the apparently not level-subtracted?