Skip to content

Commit 845b3c0

Browse files
hashkarjlenain
andauthored
Dqm update - using standard ctapipe tools (#154)
* modified charge intergration using ctapipe charge extraction methods * adjusting defaults * fixing camera plotting in charge_integration * switching from LocalPeakWindowSum to GlobalPeakWindowSum as default * Simplify existing unit tests --------- Co-authored-by: jlenain <[email protected]>
1 parent 2329514 commit 845b3c0

16 files changed

+130
-136
lines changed

src/nectarchain/dqm/camera_monitoring.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def __init__(self, gaink):
3939
self.ChargeInt_Figures_Dict = {}
4040
self.ChargeInt_Figures_Names_Dict = {}
4141

42-
def ConfigureForRun(self, path, Pix, Samp, Reader1):
42+
def ConfigureForRun(self, path, Pix, Samp, Reader1, **kwargs):
4343
# define number of pixels and samples
4444
self.Pix = Pix
4545
self.Samp = Samp

src/nectarchain/dqm/charge_integration.py

Lines changed: 71 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
11
import ctapipe.instrument.camera.readout
22
import numpy as np
33
from ctapipe.coordinates import EngineeringCameraFrame
4-
from ctapipe.image import LocalPeakWindowSum
4+
from ctapipe.image.extractor import FixedWindowSum # noqa: F401
5+
from ctapipe.image.extractor import FullWaveformSum # noqa: F401
6+
from ctapipe.image.extractor import LocalPeakWindowSum # noqa: F401
7+
from ctapipe.image.extractor import NeighborPeakWindowSum # noqa: F401
8+
from ctapipe.image.extractor import SlidingWindowMaxSum # noqa: F401
9+
from ctapipe.image.extractor import TwoPassWindowSum # noqa: F401
10+
from ctapipe.image.extractor import GlobalPeakWindowSum
511
from ctapipe.visualization import CameraDisplay
12+
from ctapipe_io_nectarcam import constants
613
from matplotlib import pyplot as plt
714
from traitlets.config.loader import Config
815

16+
from ..makers.component import ChargesComponent
17+
from ..makers.component.core import ArrayDataComponent
18+
from ..makers.extractor.utils import CtapipeExtractor
919
from .dqm_summary_processor import DQMSummary
1020

1121
__all__ = ["ChargeIntegrationHighLowGain"]
@@ -51,7 +61,7 @@ def __init__(self, gaink):
5161
self.ChargeInt_Figures_Dict = {}
5262
self.ChargeInt_Figures_Names_Dict = {}
5363

54-
def ConfigureForRun(self, path, Pix, Samp, Reader1):
64+
def ConfigureForRun(self, path, Pix, Samp, Reader1, **charges_kwargs):
5565
# define number of pixels and samples
5666
self.Pix = Pix
5767
self.Samp = Samp
@@ -72,44 +82,60 @@ def ConfigureForRun(self, path, Pix, Samp, Reader1):
7282
].camera.readout = ctapipe.instrument.camera.readout.CameraReadout.from_name(
7383
"NectarCam"
7484
)
75-
config = Config({"LocalPeakWindowSum": {"window_shift": 4, "window_width": 12}})
76-
77-
self.integrator = LocalPeakWindowSum(subarray, config=config)
85+
if charges_kwargs:
86+
extractor_kwargs = (
87+
ChargesComponent._get_extractor_kwargs_from_method_and_kwargs(
88+
method=charges_kwargs["method"],
89+
kwargs=charges_kwargs["extractor_kwargs"],
90+
)
91+
)
92+
self.integrator = eval(charges_kwargs["method"])(
93+
subarray, **extractor_kwargs
94+
)
95+
else:
96+
config = Config(
97+
{"GlobalPeakWindowSum": {"window_shift": 4, "window_width": 12}}
98+
)
99+
self.integrator = GlobalPeakWindowSum(subarray, config=config)
78100

79101
def ProcessEvent(self, evt, noped):
80-
self.pixelBAD = evt.mon.tel[0].pixel_status.hardware_failing_pixels
81102
pixel = evt.nectarcam.tel[0].svc.pixel_ids
82-
if len(pixel) < self.Pix:
83-
pixel_masked_shutter = list(
84-
np.arange(0, self.Pix - len(pixel), 1, dtype=int)
85-
)
86-
pixel = list(pixel)
87-
pixels = np.concatenate([pixel_masked_shutter, pixel])
88-
else:
89-
pixels = pixel
103+
self.pixelBADplot = evt.mon.tel[0].pixel_status.hardware_failing_pixels
104+
pixels = pixel
105+
self.pixels = pixels
90106

91-
waveform = evt.r0.tel[0].waveform[self.k]
107+
(
108+
broken_pixels_hg,
109+
broken_pixels_lg,
110+
) = ArrayDataComponent._compute_broken_pixels_event(evt, pixels)
111+
112+
if self.k == 0:
113+
self.pixelBAD = broken_pixels_hg
114+
channel = constants.HIGH_GAIN
115+
if self.k == 1:
116+
self.pixelBAD = broken_pixels_lg
117+
channel = constants.LOW_GAIN
92118

119+
waveform = evt.r0.tel[0].waveform[self.k]
120+
waveform = waveform[pixels]
93121
ped = np.mean(waveform[:, 20])
94122

95123
if noped:
96124
w_noped = waveform - ped
97-
output = self.integrator(
98-
w_noped, 0, np.zeros(self.Pix, dtype=int), self.pixelBAD
125+
output = CtapipeExtractor.get_image_peak_time(
126+
self.integrator(w_noped, 0, channel, self.pixelBAD)
99127
)
100-
image = output.image
101-
peakpos = output.peak_time
102-
image = image[pixels]
103-
peakpos = peakpos[pixels]
128+
129+
image = output[0]
130+
peakpos = output[1]
104131

105132
else:
106-
output = self.integrator(
107-
waveform, 0, np.zeros(self.Pix, dtype=int), self.pixelBAD
133+
output = CtapipeExtractor.get_image_peak_time(
134+
self.integrator(waveform, 0, channel, self.pixelBAD)
108135
)
109-
image = output.image
110-
peakpos = output.peak_time
111-
image = image[pixels]
112-
peakpos = peakpos[pixels]
136+
137+
image = output[0]
138+
peakpos = output[1]
113139

114140
if evt.trigger.event_type.value == 32: # count peds
115141
self.counter_ped += 1
@@ -274,9 +300,9 @@ def PlotResults(self, name, FigPath):
274300
# Charge integration MEAN plot
275301
if self.counter_evt > 0:
276302
fig1, disp = plt.subplots()
277-
disp = CameraDisplay(self.camera[~self.pixelBAD[0]])
303+
disp = CameraDisplay(self.camera[~self.pixelBADplot[0]])
278304
# disp = CameraDisplay(self.subarray.tels[0].camera)
279-
disp.image = self.image_all_average[~self.pixelBAD[0]]
305+
disp.image = self.image_all_average
280306
disp.cmap = plt.cm.coolwarm
281307
disp.axes.text(
282308
2,
@@ -302,8 +328,8 @@ def PlotResults(self, name, FigPath):
302328

303329
if self.counter_ped > 0:
304330
fig2, disp = plt.subplots()
305-
disp = CameraDisplay(self.camera[~self.pixelBAD[0]])
306-
disp.image = self.image_ped_average[~self.pixelBAD[0]]
331+
disp = CameraDisplay(self.camera[~self.pixelBADplot[0]])
332+
disp.image = self.image_ped_average
307333
disp.cmap = plt.cm.coolwarm
308334
disp.axes.text(
309335
2,
@@ -330,8 +356,8 @@ def PlotResults(self, name, FigPath):
330356
# Charge integration MEDIAN plot
331357
if self.counter_evt > 0:
332358
fig3, disp = plt.subplots()
333-
disp = CameraDisplay(self.camera[~self.pixelBAD[0]])
334-
disp.image = self.image_all_median[~self.pixelBAD[0]]
359+
disp = CameraDisplay(self.camera[~self.pixelBADplot[0]])
360+
disp.image = self.image_all_median
335361
disp.cmap = plt.cm.coolwarm
336362
disp.axes.text(
337363
2,
@@ -357,8 +383,8 @@ def PlotResults(self, name, FigPath):
357383

358384
if self.counter_ped > 0:
359385
fig4, disp = plt.subplots()
360-
disp = CameraDisplay(self.camera[~self.pixelBAD[0]])
361-
disp.image = self.image_ped_median[~self.pixelBAD[0]]
386+
disp = CameraDisplay(self.camera[~self.pixelBADplot[0]])
387+
disp.image = self.image_ped_median
362388
disp.cmap = plt.cm.coolwarm
363389
disp.axes.text(
364390
2,
@@ -385,8 +411,8 @@ def PlotResults(self, name, FigPath):
385411
# Charge integration STD plot
386412
if self.counter_evt > 0:
387413
fig5, disp = plt.subplots()
388-
disp = CameraDisplay(self.camera[~self.pixelBAD[0]])
389-
disp.image = self.image_all_std[~self.pixelBAD[0]]
414+
disp = CameraDisplay(self.camera[~self.pixelBADplot[0]])
415+
disp.image = self.image_all_std
390416
disp.cmap = plt.cm.coolwarm
391417
disp.axes.text(
392418
2,
@@ -412,8 +438,8 @@ def PlotResults(self, name, FigPath):
412438

413439
if self.counter_ped > 0:
414440
fig6, disp = plt.subplots()
415-
disp = CameraDisplay(self.camera[~self.pixelBAD[0]])
416-
disp.image = self.image_ped_std[~self.pixelBAD[0]]
441+
disp = CameraDisplay(self.camera[~self.pixelBADplot[0]])
442+
disp.image = self.image_ped_std
417443
disp.cmap = plt.cm.coolwarm
418444
disp.axes.text(
419445
2,
@@ -440,8 +466,8 @@ def PlotResults(self, name, FigPath):
440466
# Charge integration RMS plot
441467
if self.counter_evt > 0:
442468
fig7, disp = plt.subplots()
443-
disp = CameraDisplay(self.camera[~self.pixelBAD[0]])
444-
disp.image = self.image_all_rms[~self.pixelBAD[0]]
469+
disp = CameraDisplay(self.camera[~self.pixelBADplot[0]])
470+
disp.image = self.image_all_rms
445471
disp.cmap = plt.cm.coolwarm
446472
disp.axes.text(
447473
2,
@@ -467,8 +493,8 @@ def PlotResults(self, name, FigPath):
467493

468494
if self.counter_ped > 0:
469495
fig8, disp = plt.subplots()
470-
disp = CameraDisplay(self.camera[~self.pixelBAD[0]])
471-
disp.image = self.image_ped_rms[~self.pixelBAD[0]]
496+
disp = CameraDisplay(self.camera[~self.pixelBADplot[0]])
497+
disp.image = self.image_ped_rms
472498
disp.cmap = plt.cm.coolwarm
473499
disp.axes.text(
474500
2,
@@ -495,7 +521,7 @@ def PlotResults(self, name, FigPath):
495521
# Charge integration SPECTRUM
496522
if self.counter_evt > 0:
497523
fig9, disp = plt.subplots()
498-
for i in range(self.Pix):
524+
for i in range(len(self.pixels)):
499525
plt.hist(
500526
self.image_all[:, i],
501527
100,
@@ -532,7 +558,7 @@ def PlotResults(self, name, FigPath):
532558

533559
if self.counter_ped > 0:
534560
fig10, disp = plt.subplots()
535-
for i in range(self.Pix):
561+
for i in range(len(self.pixels)):
536562
plt.hist(
537563
self.image_ped[:, i],
538564
100,

src/nectarchain/dqm/mean_camera_display.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def __init__(self, gaink):
3131
self.MeanCameraDisplay_Figures_Dict = {}
3232
self.MeanCameraDisplay_Figures_Names_Dict = {}
3333

34-
def ConfigureForRun(self, path, Pix, Samp, Reader1):
34+
def ConfigureForRun(self, path, Pix, Samp, Reader1, **kwargs):
3535
# define number of pixels and samples
3636
self.Pix = Pix
3737
self.Samp = Samp

src/nectarchain/dqm/mean_waveforms.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def __init__(self, gaink):
2323
self.MeanWaveForms_Figures_Dict = {}
2424
self.MeanWaveForms_Figures_Names_Dict = {}
2525

26-
def ConfigureForRun(self, path, Pix, Samp, Reader1):
26+
def ConfigureForRun(self, path, Pix, Samp, Reader1, **kwargs):
2727
# define number of pixels and samples
2828
self.Pix = Pix
2929
self.Samp = Samp

src/nectarchain/dqm/pixel_participation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def __init__(self, gaink):
2525
self.PixelParticipation_Figures_Dict = {}
2626
self.PixelParticipation_Figures_Names_Dict = {}
2727

28-
def ConfigureForRun(self, path, Pix, Samp, Reader1):
28+
def ConfigureForRun(self, path, Pix, Samp, Reader1, **kwargs):
2929
# define number of pixels and samples
3030
self.Pix = Pix
3131
self.Samp = Samp

src/nectarchain/dqm/pixel_timeline.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def __init__(self, gaink):
2424
self.PixelTimeline_Figures_Dict = {}
2525
self.PixelTimeline_Figures_Names_Dict = {}
2626

27-
def ConfigureForRun(self, path, Pix, Samp, Reader1):
27+
def ConfigureForRun(self, path, Pix, Samp, Reader1, **kwargs):
2828
# define number of pixels and samples
2929
self.Pix = Pix
3030
self.Samp = Samp

src/nectarchain/dqm/runs/nectarcam_monitoring_db_2022-02-24.sqlite

Whitespace-only changes.

src/nectarchain/dqm/start_dqm.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import argparse
2+
import json
23
import os
34
import sys
45
import time
@@ -18,6 +19,7 @@
1819
from nectarchain.dqm.pixel_participation import PixelParticipationHighLowGain
1920
from nectarchain.dqm.pixel_timeline import PixelTimelineHighLowGain
2021
from nectarchain.dqm.trigger_statistics import TriggerStatistics
22+
from nectarchain.makers import ChargesNectarCAMCalibrationTool
2123

2224

2325
def main():
@@ -40,6 +42,28 @@ def main():
4042
action="store_true",
4143
help="Enables pedestal subtraction in charge integration",
4244
)
45+
# extractor arguments
46+
parser.add_argument(
47+
"--method",
48+
choices=[
49+
"FullWaveformSum",
50+
"FixedWindowSum",
51+
"GlobalPeakWindowSum",
52+
"LocalPeakWindowSum",
53+
"SlidingWindowMaxSum",
54+
"TwoPassWindowSum",
55+
],
56+
default="GlobalPeakWindowSum",
57+
help="charge extractor method",
58+
type=str,
59+
)
60+
parser.add_argument(
61+
"--extractor_kwargs",
62+
default='{"window_shift": 4, "window_width": 16}',
63+
help="charge extractor kwargs",
64+
type=json.loads,
65+
)
66+
4367
parser.add_argument(
4468
"-r",
4569
"--runnb",
@@ -94,9 +118,21 @@ def main():
94118
# Defining and printing the options
95119
PlotFig = args.plot
96120
noped = args.noped
121+
method = args.method
122+
extractor_kwargs = args.extractor_kwargs
97123

98124
print("Plot:", PlotFig)
99125
print("Noped:", noped)
126+
print("method:", method)
127+
print("extractor_kwargs:", extractor_kwargs)
128+
129+
kwargs = {"method": method, "extractor_kwargs": extractor_kwargs}
130+
charges_kwargs = {}
131+
tool = ChargesNectarCAMCalibrationTool()
132+
for key in tool.traits().keys():
133+
if key in kwargs.keys():
134+
charges_kwargs[key] = kwargs[key]
135+
print(charges_kwargs)
100136

101137
def GetName(RunFile):
102138
name = RunFile.split("/")[-1]
@@ -189,7 +225,7 @@ def CreateFigFolder(name, type):
189225
break
190226

191227
for p in processors:
192-
p.ConfigureForRun(path, Pix, Samp, reader1)
228+
p.ConfigureForRun(path, Pix, Samp, reader1, **charges_kwargs)
193229

194230
for evt in tqdm(
195231
reader, total=args.max_events if args.max_events else len(reader), unit="ev"

src/nectarchain/dqm/tests/test_camera_monitoring.py

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,9 @@
99

1010

1111
class TestCameraMonitoring:
12-
run_number = 3798
13-
max_events = 1
14-
1512
def test_camera_monitoring(self):
16-
# run_number = 3938
1713
path = get_dataset_path("NectarCAM.Run3938.30events.fits.fz")
1814

19-
config = None
20-
2115
config = Config(
2216
dict(
2317
NectarCAMEventSource=dict(
@@ -29,18 +23,17 @@ def test_camera_monitoring(self):
2923
)
3024
)
3125
)
32-
print(path)
3326

3427
reader1 = EventSource(input_url=path, config=config, max_events=1)
3528

3629
Pix, Samp = CameraMonitoring(HIGH_GAIN).DefineForRun(reader1)
3730

38-
CameraMonitoring(HIGH_GAIN).ConfigureForRun(path, Pix, Samp, reader1)
39-
31+
sql_file_date = None
4032
for evt in tqdm(reader1, total=1):
4133
run_start1 = evt.nectarcam.tel[0].svc.date
42-
SqlFileDate = astropytime.Time(run_start1, format="unix").iso.split(" ")[0]
43-
# print("SqlFileDate", SqlFileDate)
44-
# CameraMonitoring(HIGH_GAIN).FinishRun()
34+
sql_file_date = astropytime.Time(run_start1, format="unix").iso.split(" ")[
35+
0
36+
]
37+
4538
assert Pix + Samp == 1915
46-
assert SqlFileDate == "2023-01-23"
39+
assert sql_file_date == "2023-01-23"

0 commit comments

Comments
 (0)