Skip to content
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
wants to merge 115 commits into from
Closed
Show file tree
Hide file tree
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 Sep 28, 2017
66346d1
Fix doc error
FrancaCassol Oct 20, 2017
88ad9d3
Merge branch 'master' of https://github.com/cta-observatory/ctapipe
Mar 5, 2018
cff4c0b
Merge branch 'master' of https://github.com/cta-observatory/ctapipe
Mar 7, 2018
b126726
Merge branch 'master' of https://github.com/cta-observatory/ctapipe
Mar 14, 2018
ee945fb
Merge branch 'master' of https://github.com/cta-observatory/ctapipe
FrancaCassol Apr 17, 2018
828408c
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol May 7, 2018
90f77fb
LST data reader code
FrancaCassol May 11, 2018
599b72e
Add LST reader files
FrancaCassol May 11, 2018
6fc6a8d
Complete LST reader
FrancaCassol May 24, 2018
b4c6f6b
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol May 24, 2018
d4386fe
Improved container organisation: introduced EVT and SVT concept for L…
FrancaCassol May 25, 2018
31d35e1
Minor corrections
FrancaCassol May 30, 2018
fcc2f12
Style changes
FrancaCassol May 31, 2018
679fbf9
Style changes
FrancaCassol May 31, 2018
136ae43
Updated request for protozfitsreader library from release 0.44.5 to 1…
FrancaCassol May 31, 2018
e118351
Change of import from module SimpleFile to module File to be compatib…
FrancaCassol May 31, 2018
b95fbcb
remove ctapipe/atmosphere and doc/atmosphere
FrancaCassol Jun 1, 2018
3f224df
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol Jul 20, 2018
3ef7c65
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol Jul 26, 2018
902a88b
Added a check on the number of gains in the LST event.waveform
FrancaCassol Jul 26, 2018
27972b0
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol Aug 28, 2018
59b5e03
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol Aug 31, 2018
a1cb9d5
Added class MultiFiles in order to read events belonging to the same …
FrancaCassol Aug 31, 2018
937d542
Correct the protozfits version (for the moment the reader need only 1…
FrancaCassol Sep 4, 2018
e507ebb
Added comments to the MultiFiles class
FrancaCassol Sep 4, 2018
3326fb2
Ask for version protozfit 1.40 and minor code corrections
FrancaCassol Sep 5, 2018
dbaa23c
Minor changes for better coding standard
FrancaCassol Sep 6, 2018
10a23a3
Minor style changes
FrancaCassol Sep 6, 2018
3f78339
Minor changes
FrancaCassol Sep 13, 2018
c830866
Added NectarCAM reader for reading events in the new R1 format.
FrancaCassol Sep 17, 2018
26050bc
Corrected bug in reading the table CameraConfig
FrancaCassol Sep 21, 2018
2101e52
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol Sep 28, 2018
61ea071
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol Oct 3, 2018
052bace
Added LST1 TelescopeDescription with a call to TelescopeDescription.f…
FrancaCassol Oct 8, 2018
fb480e6
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol Oct 9, 2018
ef793b1
Merge branch 'LST_reader' into nectarCAM_reader
FrancaCassol Oct 9, 2018
d85b241
Correction of wrong naming
FrancaCassol Oct 9, 2018
0f88615
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol Oct 10, 2018
f7854b1
Change in hte convention of multiple file reading:
FrancaCassol Oct 10, 2018
e139cb9
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol Oct 11, 2018
8b8634a
Merge branch 'LST_reader' into nectarCAM_reader
FrancaCassol Oct 11, 2018
d6b6d57
Added to the NectarCAM reader the geometrical information of the Nec…
FrancaCassol Oct 15, 2018
7d4c033
Changed the name of the camera geometry file to PrototypeNectarCAM.ca…
FrancaCassol Oct 15, 2018
60bde0f
Prepared code for a variable number of modules present in the data
FrancaCassol Oct 15, 2018
1c043d3
Moved to protozfits libray version 1.4.2
FrancaCassol Oct 22, 2018
3bc4eb9
Moved to version 1.4.2 of the protozfits library
FrancaCassol Oct 22, 2018
9841431
Minor change
FrancaCassol Oct 22, 2018
a3600ef
Merge branch 'LST_reader' into nectarCAM_reader
FrancaCassol Oct 22, 2018
bece0ea
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol Oct 23, 2018
810c1ba
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol Oct 25, 2018
5eb005b
Minor changes
FrancaCassol Oct 25, 2018
0e18d0b
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol Oct 30, 2018
3b8de9a
- Changed the way data files are opened: Now all files of a give Run …
FrancaCassol Oct 30, 2018
070c2a8
Change name of test data file
FrancaCassol Oct 30, 2018
eb45471
Added a root container for Monitor Data: MonDataContainer and sub-con…
FrancaCassol Nov 9, 2018
06d2026
Added code for flatfield calibration
FrancaCassol Nov 19, 2018
8e67246
Changed geometry version from 1 (with bugs) to 2
FrancaCassol Nov 19, 2018
9b6f9ca
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol Nov 19, 2018
4e31c2e
Minor changes
FrancaCassol Nov 19, 2018
b54060d
Flat-field code working with the r0.waveform as input
FrancaCassol Nov 19, 2018
ffae0ac
First version of a tool for the estimation of the flat field coeffici…
FrancaCassol Nov 23, 2018
0d5a6ae
Minor style changes
FrancaCassol Nov 23, 2018
4faed1a
Merge branch 'nectarCAM_reader' into flatfield
FrancaCassol Nov 23, 2018
b8ad8b9
Moved to last version of ctapipe-extra: 0.2.15
FrancaCassol Nov 23, 2018
bffaf5b
Moved to last version of ctapipe-extra: 0.2.15
FrancaCassol Nov 23, 2018
90e57b5
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol Nov 26, 2018
7e82995
move back to ctapipe-extra version: 0.2.14
FrancaCassol Dec 3, 2018
fda3259
Go back to ctapipe-extra release 0.2.15
FrancaCassol Dec 4, 2018
089968f
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol Dec 4, 2018
ebd77b5
Added the possibility to use wild chards in the file name as in MAGIC…
FrancaCassol Dec 4, 2018
570bf3e
Merge branch 'nectarCAM_reader' into flatfield
FrancaCassol Dec 4, 2018
03519c1
Corrected code related to wildchards in input file name: for the mome…
FrancaCassol Dec 5, 2018
615b9c2
Merge branch 'nectarCAM_reader' into flatfield
FrancaCassol Dec 5, 2018
8b9b3a6
Added time to flat-field container
FrancaCassol Dec 7, 2018
3f9ff59
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
FrancaCassol Dec 17, 2018
e1f69ec
Take away ctapipe-extra==0.2.16
FrancaCassol Dec 17, 2018
3c16352
style: white-spaces; desc --> doc-string; remove indentation
Dec 18, 2018
31fbb7f
style: white-spaces
Dec 18, 2018
a28f92f
more style: white-spaces; import order; assert is not a function
Dec 18, 2018
37498b4
style: white spaces; unused imports
Dec 18, 2018
472425d
white spaces
Dec 18, 2018
ab0b60a
more white spaces
Dec 18, 2018
a86f2f5
rename `count` to `num_events_seen`; count does not say what it counts
Dec 18, 2018
55f74d9
adjust test to renamed member
Dec 18, 2018
c9d57a8
some renaming; white spaces; comments
Dec 18, 2018
df393d9
break out two functions, which could be tested outside the framework
Dec 18, 2018
443c757
no c-style backets needed in if-clause
Dec 19, 2018
277cf18
white-spaces and shorten help text
Dec 19, 2018
7b04c71
rename some fields
Dec 19, 2018
5707c26
add docu in doc-strings; clean up some doc-strings
Dec 19, 2018
d52612d
adjust test to renamed fields
Dec 19, 2018
a9063a4
rename some variables; break out more functions
Dec 19, 2018
944fc62
Added tel_id as input argument of FlatFieldCalculator and removed loo…
FrancaCassol Jan 7, 2019
ae87b2e
Changed name of FlatFieldCalculator arguments
FrancaCassol Jan 7, 2019
faddfa0
Minor changes
FrancaCassol Jan 7, 2019
e3925ec
Changed name of class FlatFieldGenaretor to FlatFieldHDF5Writer
FrancaCassol Jan 9, 2019
36b9137
Change forgotten names
FrancaCassol Jan 9, 2019
4d56184
Minor style changes
FrancaCassol Jan 13, 2019
0f5f143
Minor style changes
FrancaCassol Jan 14, 2019
7fd71dd
Merge remote-tracking branch 'upstream/master' into flatfield
Jan 16, 2019
67b0e11
Corrected bug in BaselineWaveformCleaner (wrong shape in the baseline…
FrancaCassol Jan 17, 2019
340d87d
Corrected case of MC events which do not have a pixel_status defined
FrancaCassol Jan 17, 2019
4d52dc9
remove optional deps in order to fix tests
Jan 17, 2019
c90caf2
remove tests for py3.5 since it does actually test for 3.6 only
Jan 17, 2019
ebc63ce
add py3.7 and osx to test matrix
Jan 18, 2019
7752484
xvfb does not work on osx
Jan 18, 2019
d1bd845
allow this to take 30min
Jan 18, 2019
8fcdc8f
fix typo its travis_wait .. not what I wrote before
Jan 18, 2019
1575c08
Merge remote-tracking branch 'upstream/fix_tests_on_master' into flat…
Jan 18, 2019
a83fd71
Merge branch 'flatfield' of https://github.com/FrancaCassol/ctapipe i…
FrancaCassol Jan 18, 2019
360a8a2
Moved test_pedestal.py to ctapipe/calib/camera/tests
FrancaCassol Jan 18, 2019
7218fbc
Merge branch 'master' into flatfield
Jan 22, 2019
1452449
add pytest.importorskip where needed
Jan 22, 2019
4f7fe7a
Merge branch 'master' into flatfield
Jan 29, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ install:
- pip install travis-sphinx
- pip install codecov
# ----- SST1M:
- conda install protobuf
Copy link
Member

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

- pip install https://github.com/cta-sst-1m/protozfitsreader/archive/v1.4.2.tar.gz
# ----- end of SST1M
# ----- target_software
Expand Down
2 changes: 2 additions & 0 deletions ctapipe/calib/camera/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@
from .dl0 import *
from .dl1 import *
from .calibrator import *
from .flatfield import *
from .pedestals import *
304 changes: 304 additions & 0 deletions ctapipe/calib/camera/flatfield.py
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.
22 changes: 22 additions & 0 deletions ctapipe/calib/camera/tests/test_flatfield.py
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
16 changes: 15 additions & 1 deletion ctapipe/image/waveform_cleaning.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
LocalPeakIntegrator)

__all__ = ['WaveformCleanerFactory', 'CHECMWaveformCleanerAverage',
'CHECMWaveformCleanerLocal',
'CHECMWaveformCleanerLocal','BaselineWaveformCleaner',
'NullWaveformCleaner']


Expand Down Expand Up @@ -66,6 +66,20 @@ class NullWaveformCleaner(WaveformCleaner):
def apply(self, waveforms):
return waveforms

class BaselineWaveformCleaner(WaveformCleaner):
"""
Basic waveform cleaner that simply returns the waveform subtracted
from the baseline
"""
baseline_width = Int(10, help='Define then number of samples for estimating the '
'baseline').tag(config=True)
def apply(self, waveforms):
#self.log.debug(f"calculate baseline on first {self.baseline_width} samples")
# Subtract initial baseline
baseline_sub = waveforms - np.mean(waveforms[:, :self.baseline_width], axis=1)[:, None]

return baseline_sub


class CHECMWaveformCleaner(WaveformCleaner):
"""
Expand Down
Loading