-
Notifications
You must be signed in to change notification settings - Fork 270
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
Flat-field camera corrections #870
Closed
Closed
Changes from 98 commits
Commits
Show all changes
115 commits
Select commit
Hold shift + click to select a range
f1b8096
New directory tree for the atmosphere calibration code
FrancaCassol 66346d1
Fix doc error
FrancaCassol 88ad9d3
Merge branch 'master' of https://github.com/cta-observatory/ctapipe
cff4c0b
Merge branch 'master' of https://github.com/cta-observatory/ctapipe
b126726
Merge branch 'master' of https://github.com/cta-observatory/ctapipe
ee945fb
Merge branch 'master' of https://github.com/cta-observatory/ctapipe
FrancaCassol 828408c
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol 90f77fb
LST data reader code
FrancaCassol 599b72e
Add LST reader files
FrancaCassol 6fc6a8d
Complete LST reader
FrancaCassol b4c6f6b
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol d4386fe
Improved container organisation: introduced EVT and SVT concept for L…
FrancaCassol 31d35e1
Minor corrections
FrancaCassol fcc2f12
Style changes
FrancaCassol 679fbf9
Style changes
FrancaCassol 136ae43
Updated request for protozfitsreader library from release 0.44.5 to 1…
FrancaCassol e118351
Change of import from module SimpleFile to module File to be compatib…
FrancaCassol b95fbcb
remove ctapipe/atmosphere and doc/atmosphere
FrancaCassol 3f224df
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol 3ef7c65
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol 902a88b
Added a check on the number of gains in the LST event.waveform
FrancaCassol 27972b0
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol 59b5e03
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol a1cb9d5
Added class MultiFiles in order to read events belonging to the same …
FrancaCassol 937d542
Correct the protozfits version (for the moment the reader need only 1…
FrancaCassol e507ebb
Added comments to the MultiFiles class
FrancaCassol 3326fb2
Ask for version protozfit 1.40 and minor code corrections
FrancaCassol dbaa23c
Minor changes for better coding standard
FrancaCassol 10a23a3
Minor style changes
FrancaCassol 3f78339
Minor changes
FrancaCassol c830866
Added NectarCAM reader for reading events in the new R1 format.
FrancaCassol 26050bc
Corrected bug in reading the table CameraConfig
FrancaCassol 2101e52
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol 61ea071
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol 052bace
Added LST1 TelescopeDescription with a call to TelescopeDescription.f…
FrancaCassol fb480e6
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol ef793b1
Merge branch 'LST_reader' into nectarCAM_reader
FrancaCassol d85b241
Correction of wrong naming
FrancaCassol 0f88615
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol f7854b1
Change in hte convention of multiple file reading:
FrancaCassol e139cb9
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol 8b8634a
Merge branch 'LST_reader' into nectarCAM_reader
FrancaCassol d6b6d57
Added to the NectarCAM reader the geometrical information of the Nec…
FrancaCassol 7d4c033
Changed the name of the camera geometry file to PrototypeNectarCAM.ca…
FrancaCassol 60bde0f
Prepared code for a variable number of modules present in the data
FrancaCassol 1c043d3
Moved to protozfits libray version 1.4.2
FrancaCassol 3bc4eb9
Moved to version 1.4.2 of the protozfits library
FrancaCassol 9841431
Minor change
FrancaCassol a3600ef
Merge branch 'LST_reader' into nectarCAM_reader
FrancaCassol bece0ea
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol 810c1ba
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol 5eb005b
Minor changes
FrancaCassol 0e18d0b
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol 3b8de9a
- Changed the way data files are opened: Now all files of a give Run …
FrancaCassol 070c2a8
Change name of test data file
FrancaCassol eb45471
Added a root container for Monitor Data: MonDataContainer and sub-con…
FrancaCassol 06d2026
Added code for flatfield calibration
FrancaCassol 8e67246
Changed geometry version from 1 (with bugs) to 2
FrancaCassol 9b6f9ca
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol 4e31c2e
Minor changes
FrancaCassol b54060d
Flat-field code working with the r0.waveform as input
FrancaCassol ffae0ac
First version of a tool for the estimation of the flat field coeffici…
FrancaCassol 0d5a6ae
Minor style changes
FrancaCassol 4faed1a
Merge branch 'nectarCAM_reader' into flatfield
FrancaCassol b8ad8b9
Moved to last version of ctapipe-extra: 0.2.15
FrancaCassol bffaf5b
Moved to last version of ctapipe-extra: 0.2.15
FrancaCassol 90e57b5
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol 7e82995
move back to ctapipe-extra version: 0.2.14
FrancaCassol fda3259
Go back to ctapipe-extra release 0.2.15
FrancaCassol 089968f
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol ebd77b5
Added the possibility to use wild chards in the file name as in MAGIC…
FrancaCassol 570bf3e
Merge branch 'nectarCAM_reader' into flatfield
FrancaCassol 03519c1
Corrected code related to wildchards in input file name: for the mome…
FrancaCassol 615b9c2
Merge branch 'nectarCAM_reader' into flatfield
FrancaCassol 8b9b3a6
Added time to flat-field container
FrancaCassol 3f9ff59
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol e1f69ec
Take away ctapipe-extra==0.2.16
FrancaCassol 3c16352
style: white-spaces; desc --> doc-string; remove indentation
31fbb7f
style: white-spaces
a28f92f
more style: white-spaces; import order; assert is not a function
37498b4
style: white spaces; unused imports
472425d
white spaces
ab0b60a
more white spaces
a86f2f5
rename `count` to `num_events_seen`; count does not say what it counts
55f74d9
adjust test to renamed member
c9d57a8
some renaming; white spaces; comments
df393d9
break out two functions, which could be tested outside the framework
443c757
no c-style backets needed in if-clause
277cf18
white-spaces and shorten help text
7b04c71
rename some fields
5707c26
add docu in doc-strings; clean up some doc-strings
d52612d
adjust test to renamed fields
a9063a4
rename some variables; break out more functions
944fc62
Added tel_id as input argument of FlatFieldCalculator and removed loo…
FrancaCassol ae87b2e
Changed name of FlatFieldCalculator arguments
FrancaCassol faddfa0
Minor changes
FrancaCassol e3925ec
Changed name of class FlatFieldGenaretor to FlatFieldHDF5Writer
FrancaCassol 36b9137
Change forgotten names
FrancaCassol 4d56184
Minor style changes
FrancaCassol 0f5f143
Minor style changes
FrancaCassol 7fd71dd
Merge remote-tracking branch 'upstream/master' into flatfield
67b0e11
Corrected bug in BaselineWaveformCleaner (wrong shape in the baseline…
FrancaCassol 340d87d
Corrected case of MC events which do not have a pixel_status defined
FrancaCassol 4d52dc9
remove optional deps in order to fix tests
c90caf2
remove tests for py3.5 since it does actually test for 3.6 only
ebc63ce
add py3.7 and osx to test matrix
7752484
xvfb does not work on osx
d1bd845
allow this to take 30min
8fcdc8f
fix typo its travis_wait .. not what I wrote before
1575c08
Merge remote-tracking branch 'upstream/fix_tests_on_master' into flat…
a83fd71
Merge branch 'flatfield' of https://github.com/FrancaCassol/ctapipe i…
FrancaCassol 360a8a2
Moved test_pedestal.py to ctapipe/calib/camera/tests
FrancaCassol 7218fbc
Merge branch 'master' into flatfield
1452449
add pytest.importorskip where needed
4f7fe7a
Merge branch 'master' into flatfield
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,3 +7,5 @@ | |
from .dl0 import * | ||
from .dl1 import * | ||
from .calibrator import * | ||
from .flatfield import * | ||
from .pedestals import * |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,304 @@ | ||
""" | ||
Factory for the estimation of the flat field coefficients | ||
""" | ||
from abc import abstractmethod | ||
import numpy as np | ||
from astropy import units as u | ||
from ctapipe.core import Component, Factory | ||
|
||
from ctapipe.image import ChargeExtractorFactory, WaveformCleanerFactory | ||
from ctapipe.core.traits import Int | ||
from ctapipe.io.containers import FlatFieldCameraContainer | ||
|
||
__all__ = [ | ||
'FlatFieldCalculator', | ||
'FlasherFlatFieldCalculator', | ||
'FlatFieldFactory' | ||
] | ||
|
||
|
||
class FlatFieldCalculator(Component): | ||
""" | ||
Parent class for the flat field calculators. | ||
Fills the MON.flatfield container. | ||
""" | ||
|
||
tel_id = Int( | ||
0, | ||
help='id of the telescope to calculate the flat-field coefficients' | ||
).tag(config=True) | ||
sample_duration = Int( | ||
60, | ||
help='sample duration in seconds' | ||
).tag(config=True) | ||
sample_size = Int( | ||
10000, | ||
help='sample size' | ||
).tag(config=True) | ||
n_channels = Int( | ||
2, | ||
help='number of channels to be treated' | ||
).tag(config=True) | ||
|
||
def __init__( | ||
self, | ||
config=None, | ||
tool=None, | ||
extractor_product=None, | ||
cleaner_product=None, | ||
**kwargs | ||
): | ||
""" | ||
Parent class for the flat field calculators. | ||
Fills the MON.flatfield container. | ||
|
||
Parameters | ||
---------- | ||
config : traitlets.loader.Config | ||
Configuration specified by config file or cmdline arguments. | ||
Used to set traitlet values. | ||
Set to None if no configuration to pass. | ||
tool : ctapipe.core.Tool | ||
Tool executable that is calling this component. | ||
Passes the correct logger to the component. | ||
Set to None if no Tool to pass. | ||
extractor_product : str | ||
The ChargeExtractor to use. | ||
cleaner_product : str | ||
The WaveformCleaner to use. | ||
kwargs | ||
|
||
""" | ||
super().__init__(config=config, parent=tool, **kwargs) | ||
|
||
# initialize the output | ||
self.container = FlatFieldCameraContainer() | ||
|
||
# load the waveform charge extractor and cleaner | ||
kwargs_ = dict() | ||
if extractor_product: | ||
kwargs_['product'] = extractor_product | ||
self.extractor = ChargeExtractorFactory.produce( | ||
config=config, | ||
tool=tool, | ||
**kwargs_ | ||
) | ||
self.log.info(f"extractor {self.extractor}") | ||
|
||
kwargs_ = dict() | ||
if cleaner_product: | ||
kwargs_['product'] = cleaner_product | ||
self.cleaner = WaveformCleanerFactory.produce( | ||
config=config, | ||
tool=tool, | ||
**kwargs_ | ||
) | ||
self.log.info(f"cleaner {self.cleaner}") | ||
|
||
@abstractmethod | ||
def calculate_relative_gain(self, event): | ||
"""calculate relative gain from event | ||
Parameters | ||
---------- | ||
event: DataContainer | ||
|
||
Returns: FlatFieldCameraContainer or None | ||
|
||
None is returned if no new flat field coefficients were calculated | ||
e.g. due to insufficient statistics. | ||
""" | ||
|
||
|
||
class FlasherFlatFieldCalculator(FlatFieldCalculator): | ||
|
||
def __init__(self, config=None, tool=None, **kwargs): | ||
"""Calculates flat field coefficients from flasher data | ||
|
||
based on the best algorithm described by S. Fegan in MST-CAM-TN-0060 | ||
|
||
Parameters: see base class FlatFieldCalculator | ||
""" | ||
super().__init__(config=config, tool=tool, **kwargs) | ||
|
||
self.log.info("Used events statistics : %d", self.sample_size) | ||
|
||
# members to keep state in calculate_relative_gain() | ||
self.num_events_seen = 0 | ||
self.time_start = None # trigger time of first event in sample | ||
self.charge_medians = None # med. charge in camera per event in sample | ||
self.charges = None # charge per event in sample | ||
self.arrival_times = None # arrival time per event in sample | ||
self.sample_bad_pixels = None # bad pixels per event in sample | ||
|
||
def _extract_charge(self, event): | ||
""" | ||
Extract the charge and the time from a calibration event | ||
|
||
Parameters | ||
---------- | ||
event : general event container | ||
|
||
""" | ||
|
||
waveforms = event.r0.tel[self.tel_id].waveform | ||
|
||
# Clean waveforms | ||
if self.cleaner: | ||
cleaned = self.cleaner.apply(waveforms) | ||
# do nothing | ||
else: | ||
cleaned = waveforms | ||
|
||
# Extract charge and time | ||
if self.extractor: | ||
if self.extractor.requires_neighbours(): | ||
g = event.inst.subarray.tel[self.tel_id].camera | ||
self.extractor.neighbours = g.neighbor_matrix_where | ||
|
||
charge, peak_pos, window = self.extractor.extract_charge(cleaned) | ||
|
||
# sum all the samples | ||
else: | ||
charge = cleaned.sum(axis=2) | ||
peak_pos = np.argmax(cleaned, axis=2) | ||
|
||
return charge, peak_pos | ||
|
||
def calculate_relative_gain(self, event): | ||
""" | ||
calculate the relative flat field coefficients | ||
|
||
Parameters | ||
---------- | ||
event : general event container | ||
|
||
""" | ||
|
||
# initialize the np array at each cycle | ||
waveform = event.r0.tel[self.tel_id].waveform | ||
trigger_time = event.r0.tel[self.tel_id].trigger_time | ||
pixel_status = event.r0.tel[self.tel_id].pixel_status | ||
|
||
if self.num_events_seen == 0: | ||
self.time_start = trigger_time | ||
self.setup_sample_buffers(waveform, self.sample_size) | ||
|
||
# extract the charge of the event and | ||
# the peak position (assumed as time for the moment) | ||
charge, arrival_time = self._extract_charge(event) | ||
self.collect_sample(charge, pixel_status, arrival_time) | ||
|
||
sample_age = trigger_time - self.time_start | ||
# check if to create a calibration event | ||
if ( | ||
sample_age > self.sample_duration | ||
or self.num_events_seen == self.sample_size | ||
): | ||
relative_gain_results = calculate_relative_gain_results( | ||
self.charge_medians, | ||
self.charges, | ||
self.sample_bad_pixels, | ||
) | ||
time_results = calculate_time_results( | ||
self.arrival_times, | ||
self.sample_bad_pixels, | ||
self.time_start, | ||
trigger_time, | ||
) | ||
|
||
result = { | ||
'n_events': self.num_events_seen, | ||
**relative_gain_results, | ||
**time_results, | ||
} | ||
for key, value in result.items(): | ||
setattr(self.container, key, value) | ||
|
||
self.num_events_seen = 0 | ||
return self.container | ||
|
||
else: | ||
|
||
return None | ||
|
||
def setup_sample_buffers(self, waveform, sample_size): | ||
n_channels = waveform.shape[0] | ||
n_pix = waveform.shape[1] | ||
shape = (sample_size, n_channels, n_pix) | ||
|
||
self.charge_medians = np.zeros((sample_size, n_channels)) | ||
self.charges = np.zeros(shape) | ||
self.arrival_times = np.zeros(shape) | ||
self.sample_bad_pixels = np.zeros(shape) | ||
|
||
def collect_sample(self, charge, pixel_status, arrival_time): | ||
|
||
# extract the charge of the event and | ||
# the peak position (assumed as time for the moment) | ||
bad_pixels = np.zeros(charge.shape, dtype=np.bool) | ||
bad_pixels[:] = pixel_status == 0 | ||
|
||
good_charge = np.ma.array(charge, mask=bad_pixels) | ||
charge_median = np.ma.median(good_charge, axis=1) | ||
|
||
self.charges[self.num_events_seen] = charge | ||
self.arrival_times[self.num_events_seen] = arrival_time | ||
self.sample_bad_pixels[self.num_events_seen] = bad_pixels | ||
self.charge_medians[self.num_events_seen] = charge_median | ||
self.num_events_seen += 1 | ||
|
||
|
||
def calculate_time_results( | ||
trace_time, | ||
bad_pixels_of_sample, | ||
time_start, | ||
trigger_time, | ||
): | ||
masked_trace_time = np.ma.array( | ||
trace_time, | ||
mask=bad_pixels_of_sample | ||
) | ||
|
||
# extract the average time over the camera and the events | ||
camera_time_median = np.ma.median(masked_trace_time) | ||
camera_time_mean = np.ma.mean(masked_trace_time) | ||
pixel_time_median = np.ma.median(masked_trace_time, axis=0) | ||
pixel_time_mean = np.ma.mean(masked_trace_time, axis=0) | ||
|
||
return { | ||
'time_mean': (trigger_time - time_start) / 2 * u.s, | ||
'time_range': [time_start, trigger_time] * u.s, | ||
'relative_time_median': np.ma.getdata( | ||
pixel_time_median - camera_time_median), | ||
'relative_time_mean': np.ma.getdata( | ||
pixel_time_mean - camera_time_mean), | ||
} | ||
|
||
|
||
def calculate_relative_gain_results( | ||
event_median, | ||
trace_integral, | ||
bad_pixels_of_sample, | ||
): | ||
masked_trace_integral = np.ma.array( | ||
trace_integral, | ||
mask=bad_pixels_of_sample | ||
) | ||
relative_gain_event = np.ma.getdata( | ||
masked_trace_integral / event_median[:, :, np.newaxis] | ||
) | ||
|
||
return { | ||
'relative_gain_median': np.median(relative_gain_event, axis=0), | ||
'relative_gain_mean': np.mean(relative_gain_event, axis=0), | ||
'relative_gain_rms': np.std(relative_gain_event, axis=0), | ||
} | ||
|
||
|
||
class FlatFieldFactory(Factory): | ||
""" | ||
Factory to obtain flat-field coefficients | ||
""" | ||
base = FlatFieldCalculator | ||
default = 'FlasherFlatFieldCalculator' | ||
custom_product_help = ('Flat-flield method to use') |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
from ctapipe.utils import get_dataset_path | ||
from ctapipe.io.nectarcameventsource import NectarCAMEventSource | ||
from ctapipe.calib.camera.flatfield import FlasherFlatFieldCalculator | ||
|
||
|
||
def test_FlasherFlatFieldCalculator(): | ||
|
||
example_file_path = get_dataset_path("NectarCAM.Run0890.10events.fits.fz") | ||
|
||
inputfile_reader = NectarCAMEventSource( | ||
input_url=example_file_path, | ||
max_events=10 | ||
) | ||
|
||
ff_calculator = FlasherFlatFieldCalculator(sample_size=3, tel_id=0) | ||
|
||
for event in inputfile_reader: | ||
|
||
ff_data = ff_calculator.calculate_relative_gain(event) | ||
|
||
if ff_calculator.num_events_seen == ff_calculator.sample_size: | ||
assert ff_data |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
line 58 will install protobuf, so we do not need line 57