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

DL1 writer tool (ctapipe-stage1-process) #1163

Merged
merged 156 commits into from
May 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
156 commits
Select commit Hold shift + click to select a range
c923f56
add ctapipe-stage1-process (DL1 writer) tool
kosack Oct 30, 2019
b63f2b7
add entry_point to setup.py
kosack Oct 30, 2019
67208ba
data model v2.0.0: move simulation and instrument configs to /configu…
kosack Oct 30, 2019
b3c6bd7
added sample config file, and message
kosack Oct 30, 2019
b9298ba
removed sample config from code (now in examples/config)
kosack Oct 30, 2019
75930b0
cleanup imports
kosack Oct 30, 2019
89e9b5d
add ctapipe-stage1-process (DL1 writer) tool
kosack Oct 30, 2019
bc1008c
add entry_point to setup.py
kosack Oct 30, 2019
94d943b
data model v2.0.0: move simulation and instrument configs to /configu…
kosack Oct 30, 2019
63de8e5
added sample config file, and message
kosack Oct 30, 2019
0ec0f48
removed sample config from code (now in examples/config)
kosack Oct 30, 2019
661503d
cleanup imports
kosack Oct 30, 2019
1c9ba23
use gain_selector in EventSource
kosack Nov 6, 2019
4109b08
Merge branch 'feature/dl1_tool' of https://github.com/kosack/ctapipe …
kosack Nov 6, 2019
1f929b7
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack Nov 12, 2019
5c907ce
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack Nov 12, 2019
1b9448c
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack Nov 12, 2019
81dc4ba
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack Nov 12, 2019
63af2fd
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack Nov 12, 2019
59c737b
use subarray from event_source instead of event
kosack Nov 12, 2019
accd4f1
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack Nov 13, 2019
594a5aa
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack Nov 14, 2019
2551451
change default dataset splitting to tel_id
kosack Nov 14, 2019
f0ebf41
add css fix for table bug in rtd theme
kosack Nov 18, 2019
f803876
add data model docs
kosack Nov 18, 2019
fb2efd4
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack Nov 18, 2019
599f190
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack Nov 19, 2019
daa5f35
try to re-use same hdf5 filehandle everywhere
kosack Nov 20, 2019
ddd026a
fix issue with large numner of datasets in pytables
kosack Nov 21, 2019
4c7f851
renamed DataChecker to Selector
kosack Nov 22, 2019
2c26707
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack Dec 2, 2019
7334ece
changes to support passing subarray to ImageExtractor
kosack Dec 2, 2019
1243c4c
renamed Stage1Process to Stage1ProcessorTool
kosack Dec 2, 2019
d49787f
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack Dec 11, 2019
96919ec
use ctapipe.image.ImageCleaner
kosack Dec 16, 2019
251f592
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack Jan 20, 2020
9dad7c3
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack Jan 22, 2020
63dd853
Set format version number to 1.0.0
kosack Jan 23, 2020
415d9a3
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack Feb 11, 2020
2998682
updated some metadata
kosack Feb 12, 2020
7c7f02e
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack Mar 16, 2020
b76b6f8
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack Apr 6, 2020
979a395
use and output new CameraDescription
kosack Apr 6, 2020
932b065
use ctapipe.core.QualityQuery
kosack Apr 6, 2020
748bf8f
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack Apr 8, 2020
d475ddd
switch to using new ctapipe.containers module location
kosack Apr 8, 2020
a13c9b9
fix problem with MCCameraEventContainer
kosack Apr 9, 2020
e05dc4b
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack Apr 9, 2020
d6594f3
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack Apr 16, 2020
95218bf
use metadata functions
kosack Apr 16, 2020
35d4d93
remove a useless debug statement
kosack Apr 20, 2020
ceeb280
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack Apr 27, 2020
39e69ca
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack Apr 28, 2020
3b2b497
use mask when computing concentration
kosack Apr 28, 2020
6e3c668
Remove unused imports
maxnoe Apr 28, 2020
6c1a161
Fixes and add test for the dl1 tool
maxnoe Apr 28, 2020
79a9082
Merge pull request #5 from cta-observatory/concentration_cleaning
kosack Apr 28, 2020
1487cfb
Merge branch 'feature/dl1_tool' of https://github.com/kosack/ctapipe …
kosack Apr 28, 2020
bf3040f
add missing assert
kosack Apr 28, 2020
0cf8dde
event.inst.subarray to source.subarray.inst
kosack Apr 29, 2020
26a7452
Toy source (#1298)
maxnoe Apr 28, 2020
8a781f1
Remove deprecated instrument from event container (#1294)
maxnoe Apr 28, 2020
319f92d
Rename coordinates of NominalFrame and TelescopeFrame, fixes #1260 (#…
maxnoe Apr 28, 2020
1c978b8
remove HESSIOEventSource (#1304)
kosack Apr 29, 2020
a654a2a
Add array pointing to pointing, use .tel map (#1303)
maxnoe Apr 30, 2020
3f71d01
Make arguments to enum_trait consistent, rename to create_class_enum_…
maxnoe May 6, 2020
773513e
Use np.count_nonzero instead of sum
maxnoe May 6, 2020
e6ec85b
Adapt enum trait to new master
maxnoe May 6, 2020
e8bcbc5
Also calculate skewness and kurtosis
maxnoe May 6, 2020
07bcc4f
Also calculate statistics for peak time, move containers and function
maxnoe May 6, 2020
825e28d
Add h5py to dependencies, needed for astropy.tables hdf io
maxnoe May 6, 2020
5fdc0e7
Replace 3 environment files with a call to sed
maxnoe May 6, 2020
18087cb
Implement and use island sizes
maxnoe May 6, 2020
d62dccb
Merge remote-tracking branch 'origin/master' into dl1_improvements
maxnoe May 6, 2020
38d7050
Adapt dl1 tool to new containers
maxnoe May 6, 2020
3e36eb7
Remove unused import
maxnoe May 6, 2020
4ccfee5
Move writing of instrument out of event loop and writer
maxnoe May 6, 2020
9d23384
Merge pull request #7 from cta-observatory/dl1_improvements
kosack May 6, 2020
b6a3660
Use Path for output file in stage1 tool
maxnoe May 6, 2020
8497360
Move simulation output to /simulation in hdf5
maxnoe May 6, 2020
1d783b6
Make tool output config only for debug
maxnoe May 6, 2020
63fd280
Merge remote-tracking branch 'origin/master' into more_dl1_tool_updates
maxnoe May 6, 2020
4993fa0
Make container fields follow natural hierarchy
maxnoe May 6, 2020
cb0de8e
Fix telescope list to mask, move it to the subarray description
maxnoe May 6, 2020
36f5db5
Add docstring
maxnoe May 6, 2020
fcfe347
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack May 7, 2020
7d5d02a
Merge pull request #8 from cta-observatory/more_dl1_tool_updates
kosack May 8, 2020
be488cb
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack May 8, 2020
3972352
Merge branch 'feature/dl1_tool' of https://github.com/kosack/ctapipe …
kosack May 8, 2020
0f7ecb9
Move number of islands to image.morphology, add function to calculate…
maxnoe May 8, 2020
eb0b8b6
Change MCDL1 Container to only have additioninal information
maxnoe May 8, 2020
3e2f834
Adapt tool, write true image and parameters
maxnoe May 8, 2020
565c66c
Use correct default for integers
maxnoe May 8, 2020
55ae063
Add default check to prevent hillas errors
maxnoe May 8, 2020
d55c6aa
Merge pull request #9 from cta-observatory/more_dl1_tool_updates
kosack May 11, 2020
b3a115b
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack May 11, 2020
faeac7a
Remove duplication for image paramterization
maxnoe May 11, 2020
ef79e1b
Fix imports and return value
maxnoe May 11, 2020
ac63056
Fix one more import in tests
maxnoe May 11, 2020
78cc3b5
Merge remote-tracking branch 'origin/master' into remove_duplication
maxnoe May 11, 2020
6e92eec
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack May 11, 2020
76cfdcb
uncomment write_procesing_statistics
kosack May 11, 2020
41718c4
Merge remote-tracking branch 'origin/master' into remove_duplication
maxnoe May 11, 2020
8598c2f
Fix logging for writer
maxnoe May 11, 2020
f5f8fb3
Split test in test images and paramters
maxnoe May 11, 2020
ce8cca7
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack May 11, 2020
c9d1274
Merge remote-tracking branch 'kosack/feature/dl1_tool' into remove_du…
maxnoe May 11, 2020
f872917
Fix more occurences of timing_paramters
maxnoe May 11, 2020
14e0b28
Fix one more import
maxnoe May 11, 2020
a74d6e9
Merge pull request #10 from cta-observatory/remove_duplication
kosack May 11, 2020
32a8716
Merge branch 'feature/dl1_tool' of https://github.com/kosack/ctapipe …
kosack May 11, 2020
6bda781
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack May 11, 2020
7ba989e
fix import
kosack May 11, 2020
7991ad7
Fix missing h5py in setup, missing overwrite
maxnoe May 11, 2020
fa81bb5
added back h5py, accidentally removed
kosack May 11, 2020
3a5f99a
Move writing with h5py out of writer block
maxnoe May 11, 2020
44c6a3c
Fix wrong kwarg in metadata
maxnoe May 11, 2020
23bb3b9
Merge branch 'feature/dl1_tool' into fix_travis
maxnoe May 11, 2020
8cfd582
Merge pull request #11 from cta-observatory/fix_travis
kosack May 11, 2020
834edd8
change /simulation/run to /simulation/service
kosack May 11, 2020
917ad89
change /simulation/run to /simulation/service
kosack May 11, 2020
08e9b92
Merge branch 'feature/dl1_tool' of https://github.com/kosack/ctapipe …
kosack May 11, 2020
fe195d1
reformat and optimize imports
kosack May 11, 2020
6d84130
Remove unused fields from mc header
maxnoe May 11, 2020
0da7f86
Exclude correct columns to avoid warnings
maxnoe May 11, 2020
78d6680
Fix column exclusions in stage1 writer
maxnoe May 11, 2020
90d5cb9
Merge pull request #12 from cta-observatory/more_dl1
kosack May 11, 2020
1bb8bb3
Exclude mc timing columns
maxnoe May 11, 2020
d1c483f
Merge pull request #13 from cta-observatory/exclude_mc_time
kosack May 12, 2020
2bf33b3
Adapt to updates to event source
maxnoe May 12, 2020
203b5d4
Merge remote-tracking branch 'origin/master' into event_source_updates
maxnoe May 12, 2020
eac9df3
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack May 12, 2020
07b8b52
Merge pull request #14 from cta-observatory/event_source_updates
kosack May 12, 2020
75b3846
reformat and optimize imports
kosack May 12, 2020
fcf761d
small fixes (see details below)
kosack May 12, 2020
24e286f
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack May 12, 2020
5661ff1
revert classes_with_traits(EventSource) back to only the base class
kosack May 13, 2020
42cd538
cur_obs_id -> event_source.obs_id
maxnoe May 13, 2020
1bc7bab
Add missing f string
maxnoe May 13, 2020
a3ac9c7
Merge remote-tracking branch 'origin/master' into dl1_fixes
maxnoe May 13, 2020
cf8692c
Write trigger times
maxnoe May 13, 2020
3db5a02
Merge pull request #16 from cta-observatory/dl1_fixes
kosack May 13, 2020
cef3998
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack May 14, 2020
e1315fe
Store pointing info in dl1 tool
maxnoe May 12, 2020
829dd93
Only compare to last pointing
maxnoe May 13, 2020
92a15e7
Move pointing into dl1
maxnoe May 13, 2020
1130f6e
Store pointing vs. time in telescope wise containers
maxnoe May 14, 2020
a963221
Merge pull request #15 from cta-observatory/stage1_pointing
kosack May 14, 2020
704faea
stage1: Use zstd compression by default
maxnoe May 14, 2020
46405bf
Merge pull request #17 from cta-observatory/zstd_stage1
kosack May 14, 2020
83f14b0
Improve defaults in stage1 config example
maxnoe May 14, 2020
8cd2a7e
Merge pull request #18 from cta-observatory/stage1_config
kosack May 14, 2020
9cef9fc
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack May 18, 2020
f79a677
Merge branch 'master' of https://github.com/cta-observatory/ctapipe i…
kosack May 18, 2020
1d7b842
Merge remote-tracking branch 'origin/master' into feature/dl1_tool
maxnoe May 18, 2020
8f76a39
remove forced naming of mc → true
kosack May 18, 2020
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
6 changes: 3 additions & 3 deletions ci/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ if [[ "$CONDA" == "true" ]]; then
# Useful for debugging any issues with conda
conda info -a

sed -i -e "s/- python=.*/- python=$PYTHON_VERSION/g" environment.yml
travis_wait 20 conda env create -n cta-dev --file environment.yml
conda activate cta-dev
sed -i -e "s/- python=.*/- python=$TRAVIS_PYTHON_VERSION/g" environment.yml
travis_wait 20 conda env create -n cta-dev --file environment.yml
conda activate cta-dev
else
pip install -U pip
fi
46 changes: 35 additions & 11 deletions ctapipe/containers.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,20 +83,19 @@ class EventType(enum.Enum):

class EventIndexContainer(Container):
""" index columns to include in event lists, common to all data levels"""

container_prefix = "" # don't want to prefix these

event_id = Field(0, "event identifier")
obs_id = Field(0, "observation identifier")
event_id = Field(0, "event identifier")


class TelEventIndexContainer(EventIndexContainer):
class TelEventIndexContainer(Container):
"""
index columns to include in telescope-wise event lists, common to all data
levels that have telescope-wise information
"""

container_prefix = "" # don't want to prefix these
obs_id = Field(0, "observation identifier")
event_id = Field(0, "event identifier")
tel_id = Field(0, "telescope identifier")


Expand Down Expand Up @@ -181,11 +180,30 @@ class TimingParametersContainer(Container):
class MorphologyContainer(Container):
""" Parameters related to pixels surviving image cleaning """

num_pixels = Field(nan, "Number of usable pixels")
num_islands = Field(nan, "Number of distinct islands in the image")
num_small_islands = Field(nan, "Number of <= 2 pixel islands")
num_medium_islands = Field(nan, "Number of 2-50 pixel islands")
num_large_islands = Field(nan, "Number of > 10 pixel islands")
num_pixels = Field(-1, "Number of usable pixels")
num_islands = Field(-1, "Number of distinct islands in the image")
num_small_islands = Field(-1, "Number of <= 2 pixel islands")
num_medium_islands = Field(-1, "Number of 2-50 pixel islands")
num_large_islands = Field(-1, "Number of > 50 pixel islands")


class StatisticsContainer(Container):
"""Store descriptive statistics"""

max = Field(nan, "value of pixel with maximum intensity")
min = Field(nan, "value of pixel with minimum intensity")
mean = Field(nan, "mean intensity")
std = Field(nan, "standard deviation of intensity")
skewness = Field(nan, "skewness of intensity")
kurtosis = Field(nan, "kurtosis of intensity")


class IntensityStatisticsContainer(StatisticsContainer):
container_prefix = "intensity"


class PeakTimeStatisticsContainer(StatisticsContainer):
container_prefix = "peak_time"


class ImageParametersContainer(Container):
Expand All @@ -197,6 +215,12 @@ class ImageParametersContainer(Container):
leakage = Field(LeakageContainer(), "Leakage Parameters")
concentration = Field(ConcentrationContainer(), "Concentration Parameters")
morphology = Field(MorphologyContainer(), "Image Morphology Parameters")
intensity_statistics = Field(
IntensityStatisticsContainer(), "Intensity image statistics"
)
peak_time_statistics = Field(
PeakTimeStatisticsContainer(), "Peak time image statistics"
)


class DL1CameraContainer(Container):
Expand Down Expand Up @@ -230,7 +254,7 @@ class DL1CameraContainer(Container):
parameters = Field(ImageParametersContainer(), "Parameters derived from images")


class MCDL1CameraContainer(DL1CameraContainer):
class MCDL1CameraContainer(Container):
""" Contains all fields of the DL1CameraContainer, but adds fields for simulated
DL1 image information."""

Expand Down
2 changes: 1 addition & 1 deletion ctapipe/core/tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ def run(self, argv=None):
Provenance().start_activity(self.name)
self.setup()
self.is_setup = True
self.log.info(f"CONFIG: {self.get_current_config()}")
self.log.debug(f"CONFIG: {self.get_current_config()}")
Provenance().add_config(self.get_current_config())
self.start()
self.finish()
Expand Down
19 changes: 15 additions & 4 deletions ctapipe/image/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
from .hillas import *
from .hillas import (
hillas_parameters, HillasParameterizationError, camera_to_shower_coordinates,
)
from .timing import timing_parameters
from .leakage import leakage
from .concentration import concentration
from .statistics import descriptive_statistics
from .morphology import (
number_of_islands,
number_of_island_sizes,
morphology_parameters,
largest_island,
)

from .cleaning import *
from .pixel_likelihood import *
from .extractor import *
from .reducer import *
from .muon import *
from .geometry_converter import *
from .leakage import *
from .concentration import concentration
from .muon import *
62 changes: 0 additions & 62 deletions ctapipe/image/cleaning.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,13 @@
"mars_cleaning_1st_pass",
"fact_image_cleaning",
"apply_time_delta_cleaning",
"number_of_islands",
"ImageCleaner",
"TailcutsImageCleaner",
]

from abc import abstractmethod

import numpy as np
from scipy.sparse.csgraph import connected_components

from ..core.component import TelescopeComponent
from ..core.traits import (
Expand Down Expand Up @@ -202,42 +200,6 @@ def dilate(geom, mask):
return mask | geom.neighbor_matrix_sparse.dot(mask)


def number_of_islands(geom, mask):
"""
Search a given pixel mask for connected clusters.
This can be used to seperate between gamma and hadronic showers.

Parameters
----------
geom: `~ctapipe.instrument.CameraGeometry`
Camera geometry information
mask: ndarray
input mask (array of booleans)

Returns
-------
num_islands: int
Total number of clusters
island_labels: ndarray
Contains cluster membership of each pixel.
Dimension equals input geometry.
Entries range from 0 (not in the pixel mask) to num_islands.
"""
# compress sparse neighbor matrix
neighbor_matrix_compressed = geom.neighbor_matrix_sparse[mask][:, mask]
# pixels in no cluster have label == 0
island_labels = np.zeros(geom.n_pixels, dtype="int32")

num_islands, island_labels_compressed = connected_components(
neighbor_matrix_compressed, directed=False
)

# count clusters from 1 onwards
island_labels[mask] = island_labels_compressed + 1

return num_islands, island_labels


def apply_time_delta_cleaning(
geom, mask, arrival_times, min_number_neighbors, time_limit
):
Expand Down Expand Up @@ -367,30 +329,6 @@ def fact_image_cleaning(
return pixels_to_keep


def largest_island(islands_labels):
"""Find the biggest island and filter it from the image.

This function takes a list of islands in an image and isolates the largest one
for later parametrization.

Parameters
----------
islands_labels : array
Flattened array containing a list of labelled islands from a cleaned image.
Second value returned by the function 'number_of_islands'.

Returns
-------
islands_labels : array
A boolean mask created from the input labels and filtered for the largest island.
If no islands survived the cleaning the array is all False.

"""
if np.count_nonzero(islands_labels) == 0:
return np.zeros(islands_labels.shape, dtype="bool")
return islands_labels == np.argmax(np.bincount(islands_labels[islands_labels > 0]))


class ImageCleaner(TelescopeComponent):
"""
Abstract class for all configurable Image Cleaning algorithms. Use
Expand Down
4 changes: 2 additions & 2 deletions ctapipe/image/extractor.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
from ctapipe.core import TelescopeComponent
from numba import njit, prange, guvectorize, float64, float32, int64

from .cleaning import number_of_islands, largest_island, tailcuts_clean
from .timing_parameters import timing_parameters
from . import number_of_islands, largest_island, tailcuts_clean
from .timing import timing_parameters
from .hillas import hillas_parameters, camera_to_shower_coordinates


Expand Down
126 changes: 126 additions & 0 deletions ctapipe/image/morphology.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import numpy as np
from scipy.sparse.csgraph import connected_components

from ..containers import MorphologyContainer


def number_of_islands(geom, mask):
"""
Search a given pixel mask for connected clusters.
This can be used to seperate between gamma and hadronic showers.

Parameters
----------
geom: `~ctapipe.instrument.CameraGeometry`
Camera geometry information
mask: ndarray
input mask (array of booleans)

Returns
-------
num_islands: int
Total number of clusters
island_labels: ndarray
Contains cluster membership of each pixel.
Dimension equals input geometry.
Entries range from 0 (not in the pixel mask) to num_islands.
"""
# compress sparse neighbor matrix
neighbor_matrix_compressed = geom.neighbor_matrix_sparse[mask][:, mask]
# pixels in no cluster have label == 0
island_labels = np.zeros(geom.n_pixels, dtype="int32")

num_islands, island_labels_compressed = connected_components(
neighbor_matrix_compressed, directed=False
)

# count clusters from 1 onwards
island_labels[mask] = island_labels_compressed + 1

return num_islands, island_labels


def number_of_island_sizes(island_labels):
'''
Return number of small, medium and large islands

Parameters
----------
island_labels: array[int]
Array with island labels, (second return value of ``number_of_islands``)

Returns
-------
n_small: int
number of islands with less than 3 pixels
n_medium: int
number of islands with 3 <= n_pixels <= 50
n_large: int
number of islands with more than 50 pixels
'''

# count number of pixels in each island, remove 0 = no island
island_sizes = np.bincount(island_labels)[1:]

# remove islands of size 0 (if labels are not consecutive)
# should not happen, but easy to check
island_sizes = island_sizes[island_sizes > 0]

small = island_sizes <= 2
large = island_sizes > 50
n_medium = np.count_nonzero(~(small | large))

return np.count_nonzero(small), n_medium, np.count_nonzero(large)


def largest_island(islands_labels):
"""Find the biggest island and filter it from the image.

This function takes a list of islands in an image and isolates the largest one
for later parametrization.

Parameters
----------
islands_labels : array
Flattened array containing a list of labelled islands from a cleaned image.
Second value returned by the function 'number_of_islands'.

Returns
-------
islands_labels : array
A boolean mask created from the input labels and filtered for the largest island.
If no islands survived the cleaning the array is all False.

"""
if np.count_nonzero(islands_labels) == 0:
return np.zeros(islands_labels.shape, dtype="bool")
return islands_labels == np.argmax(np.bincount(islands_labels[islands_labels > 0]))


def morphology_parameters(geom, image_mask) -> MorphologyContainer:
"""
Compute image morphology parameters

Parameters
----------
geom: ctapipe.instrument.camera.CameraGeometry
camera description
image_mask: np.ndarray(bool)
image of pixels surviving cleaning (True=survives)

Returns
-------
MorphologyContainer: parameters related to the morphology
"""

num_islands, island_labels = number_of_islands(geom=geom, mask=image_mask)

n_small, n_medium, n_large = number_of_island_sizes(island_labels)

return MorphologyContainer(
num_pixels=np.count_nonzero(image_mask),
num_islands=num_islands,
num_small_islands=n_small,
num_medium_islands=n_medium,
num_large_islands=n_large,
)
15 changes: 15 additions & 0 deletions ctapipe/image/statistics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from scipy.stats import skew, kurtosis

from ..containers import StatisticsContainer


def descriptive_statistics(values, container_class=StatisticsContainer) -> StatisticsContainer:
""" compute intensity statistics of an image """
return container_class(
max=values.max(),
min=values.min(),
mean=values.mean(),
std=values.std(),
skewness=skew(values),
kurtosis=kurtosis(values),
)
Loading