def test_display_dl1(tmpdir, dl1_image_file, dl1_parameters_file): from ctapipe.tools.display_dl1 import DisplayDL1Calib mpl.use("Agg") # test simtel assert ( run_tool( DisplayDL1Calib(), argv=shlex.split("--max_events=1 " "--telescope=11 "), cwd=tmpdir, ) == 0 ) # test DL1A assert ( run_tool( DisplayDL1Calib(), argv=shlex.split( f"--input {dl1_image_file} --max_events=1 " "--telescope=11 " ), ) == 0 ) # test DL1B assert ( run_tool( DisplayDL1Calib(), argv=shlex.split( f"--input {dl1_parameters_file} --max_events=1 " "--telescope=11 " ), ) == 1 ) assert run_tool(DisplayDL1Calib(), ["--help-all"]) == 0
def test_telescope_parameter_from_cli(mock_subarray): """ Test we can pass single default for telescope components via cli see #1559 """ from ctapipe.core import Tool, run_tool class SomeComponent(TelescopeComponent): path = TelescopeParameter(Path(), default_value=None).tag(config=True) val = TelescopeParameter(Float(), default_value=1.0).tag(config=True) class TelescopeTool(Tool): def setup(self): self.comp = SomeComponent(subarray=mock_subarray, parent=self) tool = TelescopeTool() run_tool(tool) assert tool.comp.path == [("type", "*", None)] assert tool.comp.val == [("type", "*", 1.0)] tool = TelescopeTool() run_tool(tool, ["--SomeComponent.path", "test.h5", "--SomeComponent.val", "2.0"]) assert tool.comp.path == [("type", "*", pathlib.Path("test.h5").absolute())] assert tool.comp.val == [("type", "*", 2.0)]
def test_muon_reconstruction(tmpdir): from ctapipe.tools.muon_reconstruction import MuonDisplayerTool assert run_tool(MuonDisplayerTool(), argv=shlex.split(f"--input={GAMMA_TEST_LARGE} " "--max_events=2 ")) == 0 assert run_tool(MuonDisplayerTool(), ["--help-all"]) == 0
def test_display_dl1(tmp_path, dl1_image_file, dl1_parameters_file): from ctapipe.tools.display_dl1 import DisplayDL1Calib mpl.use("Agg") # test simtel assert ( run_tool( DisplayDL1Calib(), argv=["--max-events=1", "--telescope=11"], cwd=tmp_path ) == 0 ) # test DL1A assert ( run_tool( DisplayDL1Calib(), argv=[f"--input={dl1_image_file}", "--max-events=1", "--telescope=11"], ) == 0 ) # test DL1B, should error since nothing to plot ret = run_tool( DisplayDL1Calib(), argv=[f"--input={dl1_parameters_file}", "--max-events=1", "--telescope=11"], ) assert ret == 1 assert run_tool(DisplayDL1Calib(), ["--help-all"]) == 0
def test_bokeh_file_viewer(tmpdir): from ctapipe.tools.bokeh.file_viewer import BokehFileViewer sys.argv = ["bokeh_file_viewer"] tool = BokehFileViewer(disable_server=True) assert run_tool(tool, cwd=tmpdir) == 0 assert tool.reader.input_url == get_dataset_path("gamma_test_large.simtel.gz") assert run_tool(tool, ["--help-all"]) == 0
def test_extract_charge_resolution(tmpdir): from ctapipe.tools.extract_charge_resolution import ChargeResolutionGenerator output_path = os.path.join(str(tmpdir), "cr.h5") tool = ChargeResolutionGenerator() assert run_tool(tool, ["-f", GAMMA_TEST_LARGE, "-O", output_path]) == 1 # TODO: Test files do not contain true charge, cannot test tool fully # assert os.path.exists(output_path) assert run_tool(tool, ["--help-all"]) == 0
def test_display_summed_images(tmpdir): from ctapipe.tools.display_summed_images import ImageSumDisplayerTool mpl.use("Agg") assert run_tool(ImageSumDisplayerTool(), argv=shlex.split(f"--infile={GAMMA_TEST_LARGE} " "--max-events=2 ")) == 0 assert run_tool(ImageSumDisplayerTool(), ["--help-all"]) == 0
def test_display_integrator(tmpdir): from ctapipe.tools.display_integrator import DisplayIntegrator mpl.use("Agg") assert run_tool(DisplayIntegrator(), argv=shlex.split(f"--f={GAMMA_TEST_LARGE} " "--max_events=1 ")) == 0 assert run_tool(DisplayIntegrator(), ["--help-all"]) == 0
def test_display_dl1(tmpdir): from ctapipe.tools.display_dl1 import DisplayDL1Calib mpl.use("Agg") assert run_tool(DisplayDL1Calib(), argv=shlex.split("--max_events=1 " "--telescope=11 ")) == 0 assert run_tool(DisplayDL1Calib(), ["--help-all"]) == 0
def test_dump_triggers(tmp_path): from ctapipe.tools.dump_triggers import DumpTriggersTool sys.argv = ["dump_triggers"] outfile = tmp_path / "triggers.fits" tool = DumpTriggersTool(infile=PROD5B_PATH, outfile=str(outfile)) assert run_tool(tool, cwd=tmp_path) == 0 assert outfile.exists() assert run_tool(tool, ["--help-all"]) == 0
def test_stage_1(): from ctapipe.tools.stage1 import Stage1ProcessorTool with tempfile.NamedTemporaryFile(suffix='.hdf5') as f: assert run_tool(Stage1ProcessorTool(), argv=[ '--config=./examples/stage1_config.json', f"--input={GAMMA_TEST_LARGE}", f'--output={f.name}', '--write-parameters', '--overwrite', ]) == 0 # check tables were written with tables.open_file(f.name, mode='r') as tf: assert tf.root.dl1 assert tf.root.dl1.event.telescope assert tf.root.dl1.event.subarray assert tf.root.configuration.instrument.subarray.layout assert tf.root.configuration.instrument.telescope.optics assert tf.root.configuration.instrument.telescope.camera.geometry_LSTCam assert tf.root.configuration.instrument.telescope.camera.readout_LSTCam # check we can read telescope parametrs dl1_features = pd.read_hdf(f.name, '/dl1/event/telescope/parameters/tel_001') features = ('obs_id', 'event_id', 'tel_id', 'hillas_intensity', 'concentration_cog', 'leakage_pixels_width_1') for feature in features: assert feature in dl1_features.columns with tempfile.NamedTemporaryFile(suffix='.hdf5') as f: assert run_tool(Stage1ProcessorTool(), argv=[ '--config=./examples/stage1_config.json', f"--input={GAMMA_TEST_LARGE}", f'--output={f.name}', '--write-images', '--overwrite', ]) == 0 with tables.open_file(f.name, mode='r') as tf: assert tf.root.dl1 assert tf.root.dl1.event.telescope assert tf.root.dl1.event.subarray assert tf.root.configuration.instrument.subarray.layout assert tf.root.configuration.instrument.telescope.optics assert tf.root.configuration.instrument.telescope.camera.geometry_LSTCam assert tf.root.configuration.instrument.telescope.camera.readout_LSTCam assert tf.root.dl1.event.telescope.images.tel_001 dl1_image = tf.root.dl1.event.telescope.images.tel_001 assert 'image_mask' in dl1_image.dtype.names assert 'image' in dl1_image.dtype.names assert 'peak_time' in dl1_image.dtype.names
def test_camdemo(tmpdir): from ctapipe.tools.camdemo import CameraDemo sys.argv = ["camera_demo"] tool = CameraDemo() tool.num_events = 10 tool.cleanframes = 2 tool.display = False assert run_tool(tool, cwd=tmpdir) == 0 assert run_tool(tool, ["--help-all"]) == 0
def test_display_summed_images(tmp_path): from ctapipe.tools.display_summed_images import ImageSumDisplayerTool mpl.use("Agg") assert (run_tool( ImageSumDisplayerTool(), argv=[f"--infile={GAMMA_TEST_LARGE}", "--max-events=2"], cwd=tmp_path, ) == 0) assert run_tool(ImageSumDisplayerTool(), ["--help-all"]) == 0
def test_dump_instrument(tmpdir): from ctapipe.tools.dump_instrument import DumpInstrumentTool sys.argv = ["dump_instrument"] tmpdir.chdir() tool = DumpInstrumentTool(infile=GAMMA_TEST_LARGE, ) assert run_tool(tool) == 0 assert tmpdir.join("FlashCam.camgeom.fits.gz").exists() assert run_tool(tool, ["--help-all"]) == 0
def test_dump_triggers(tmpdir): from ctapipe.tools.dump_triggers import DumpTriggersTool sys.argv = ["dump_triggers"] outfile = tmpdir.join("triggers.fits") tool = DumpTriggersTool(infile=GAMMA_TEST_LARGE, outfile=str(outfile)) assert run_tool(tool, cwd=tmpdir) == 0 assert outfile.exists() assert run_tool(tool, ["--help-all"]) == 0
def test_display_integrator(tmp_path): from ctapipe.tools.display_integrator import DisplayIntegrator mpl.use("Agg") assert (run_tool( DisplayIntegrator(), argv=[f"--input={GAMMA_TEST_LARGE}", "--max-events=1"], cwd=tmp_path, ) == 0) assert run_tool(DisplayIntegrator(), ["--help-all"]) == 0
def test_plot_charge_resolution(tmpdir): from ctapipe.tools.plot_charge_resolution import ChargeResolutionViewer from ctapipe.plotting.tests.test_charge_resolution import create_temp_cr_file path = create_temp_cr_file(tmpdir) output_path = os.path.join(str(tmpdir), "cr.pdf") tool = ChargeResolutionViewer() assert run_tool(tool, ["-f", [path], "-o", output_path]) == 0 assert os.path.exists(output_path) assert run_tool(tool, ["--help-all"]) == 0
def test_display_events_single_tel(tmpdir): from ctapipe.tools.display_events_single_tel import SingleTelEventDisplay mpl.use("Agg") assert run_tool( SingleTelEventDisplay(), argv=shlex.split(f"--infile={GAMMA_TEST_LARGE} " "--tel=11 " "--max-events=2 " # <--- inconsistent!!! )) == 0 assert run_tool(SingleTelEventDisplay(), ["--help-all"]) == 0
def test_muon_reconstruction(tmpdir): from ctapipe.tools.muon_reconstruction import MuonAnalysis with tempfile.NamedTemporaryFile(suffix=".hdf5") as f: assert (run_tool( MuonAnalysis(), argv=[f"--input={LST_MUONS}", f"--output={f.name}", "--overwrite"], ) == 0) with tables.open_file(f.name) as t: table = t.root.dl1.event.telescope.parameters.muons[:] assert len(table) > 20 assert np.count_nonzero(np.isnan(table["muonring_radius"])) == 0 assert run_tool(MuonAnalysis(), ["--help-all"]) == 0
def test_create_irf_point_like_srcdep_energy_dependent_cuts( temp_dir_observed_srcdep_files, simulated_srcdep_dl2_file ): """ Generating point-like source-dependent IRF file from a test DL2 files, using energy-dependent cuts """ from lstchain.tools.lstchain_create_irf_files import IRFFITSWriter from astropy.table import QTable irf_file = temp_dir_observed_srcdep_files / "irf_edep.fits.gz" assert ( run_tool( IRFFITSWriter(), argv=[ f"--input-gamma-dl2={simulated_srcdep_dl2_file}", f"--output-irf-file={irf_file}", "--point-like", "--source-dep", "--energy-dependent-gh", "--energy-dependent-alpha", "--overwrite", ], cwd=temp_dir_observed_srcdep_files, ) == 0 ) gh_cuts = QTable.read(irf_file, hdu="GH_CUTS") assert isinstance(gh_cuts.meta["GH_EFF"], float) al_cuts = QTable.read(irf_file, hdu="AL_CUTS") assert isinstance(al_cuts.meta["AL_CONT"], float)
def test_create_dl3_with_config(temp_dir_observed_files, observed_dl2_file): """ Generating an DL3 file from a test DL2 files and test IRF file, using a config file """ from lstchain.tools.lstchain_create_dl3_file import DataReductionFITSWriter irf_file = temp_dir_observed_files / "fe_irf.fits.gz" config_file = os.path.join(os.getcwd(), "docs/examples/dl3_tool_config.json") assert ( run_tool( DataReductionFITSWriter(), argv=[ f"--input-dl2={observed_dl2_file}", f"--output-dl3-path={temp_dir_observed_files}", f"--input-irf={irf_file}", "--source-name=Crab", "--source-ra=83.633deg", "--source-dec=22.01deg", f"--config={config_file}", "--overwrite", ], cwd=temp_dir_observed_files, ) == 0 )
def test_create_srcdep_dl3( temp_dir_observed_srcdep_files, observed_srcdep_dl2_file, simulated_srcdep_irf_file ): """ Generating a source-dependent DL3 file from a test DL2 files and test IRF file """ from lstchain.tools.lstchain_create_dl3_file import DataReductionFITSWriter from lstchain.paths import dl2_to_dl3_filename assert ( run_tool( DataReductionFITSWriter(), argv=[ f"--input-dl2={observed_srcdep_dl2_file}", f"--output-dl3-path={temp_dir_observed_srcdep_files}", f"--input-irf={simulated_srcdep_irf_file}", "--source-name=Crab", "--source-ra=83.633deg", "--source-dec=22.01deg", "--source-dep", "--overwrite", ], cwd=temp_dir_observed_srcdep_files, ) == 0 ) hdulist = fits.open( temp_dir_observed_srcdep_files / dl2_to_dl3_filename(observed_srcdep_dl2_file) ) ra = hdulist[1].data['RA'] dec = hdulist[1].data['DEC'] np.testing.assert_allclose(ra, 83.63, atol=1e-2) np.testing.assert_allclose(dec, 22.01, atol=1e-2)
def test_create_irf_point_like(temp_dir_observed_files, simulated_dl2_file): """ Generating point-like IRF file from a test DL2 files """ from lstchain.tools.lstchain_create_irf_files import IRFFITSWriter irf_file = temp_dir_observed_files / "pnt_irf.fits.gz" assert ( run_tool( IRFFITSWriter(), argv=[ f"--input-gamma-dl2={simulated_dl2_file}", f"--input-proton-dl2={simulated_dl2_file}", f"--input-electron-dl2={simulated_dl2_file}", f"--output-irf-file={irf_file}", "--point-like", "--overwrite", ], cwd=temp_dir_observed_files, ) == 0 ) with fits.open(irf_file) as hdul: for hdu in hdul[1:]: assert 'RAD_MAX' in hdu.header assert isinstance(hdu.header['RAD_MAX'], float)
def test_create_srcdep_dl3_energy_dependent_cuts( temp_dir_observed_srcdep_files, observed_srcdep_dl2_file ): """ Generating a source-dependent DL3 file from a test DL2 files and test IRF file, using energy-dependent cuts """ from lstchain.tools.lstchain_create_dl3_file import DataReductionFITSWriter irf_file = temp_dir_observed_srcdep_files / "irf_edep.fits.gz" assert ( run_tool( DataReductionFITSWriter(), argv=[ f"--input-dl2={observed_srcdep_dl2_file}", f"--output-dl3-path={temp_dir_observed_srcdep_files}", f"--input-irf={irf_file}", "--source-name=Crab", "--source-ra=83.633deg", "--source-dec=22.01deg", "--source-dep", "--overwrite", ], cwd=temp_dir_observed_srcdep_files, ) == 0 )
def test_create_irf_full_enclosure_with_config(temp_dir_observed_files, simulated_dl2_file): """ Generating full enclosure IRF file from a test DL2 files, using a config file """ from lstchain.tools.lstchain_create_irf_files import IRFFITSWriter irf_file = temp_dir_observed_files / "fe_irf.fits.gz" config_file = os.path.join(os.getcwd(), "./docs/examples/irf_tool_config.json") assert ( run_tool( IRFFITSWriter(), argv=[ f"--input-gamma-dl2={simulated_dl2_file}", f"--input-proton-dl2={simulated_dl2_file}", f"--input-electron-dl2={simulated_dl2_file}", f"--output-irf-file={irf_file}", f"--config={config_file}", "--overwrite", ], cwd=temp_dir_observed_files, ) == 0 )
def test_create_irf_point_like_srcdep( temp_dir_observed_srcdep_files, simulated_srcdep_dl2_file ): """ Generating point-like source-dependent IRF file from a test DL2 files """ from lstchain.tools.lstchain_create_irf_files import IRFFITSWriter irf_file = temp_dir_observed_srcdep_files / "irf.fits.gz" assert ( run_tool( IRFFITSWriter(), argv=[ f"--input-gamma-dl2={simulated_srcdep_dl2_file}", f"--output-irf-file={irf_file}", "--point-like", "--source-dep", "--overwrite", ], cwd=temp_dir_observed_srcdep_files, ) == 0 ) with fits.open(irf_file) as hdul: for hdu in hdul[1:]: assert 'AL_CUT' in hdu.header assert isinstance(hdu.header['AL_CUT'], float)
def test_image_modifications(tmp_path, dl1_image_file): """ Test that running ctapipe-process with an ImageModifier set produces a file with different images. """ unmodified_images = read_table(dl1_image_file, "/dl1/event/telescope/images/tel_025") noise_config = resource_file("image_modification_config.json") dl1_modified = tmp_path / "dl1_modified.dl1.h5" assert (run_tool( ProcessorTool(), argv=[ f"--config={noise_config}", f"--input={dl1_image_file}", f"--output={dl1_modified}", "--write-parameters", "--overwrite", ], cwd=tmp_path, ) == 0) modified_images = read_table(dl1_modified, "/dl1/event/telescope/images/tel_025") # Test that significantly more light is recorded (bias in dim pixels) assert modified_images["image"].sum() / unmodified_images["image"].sum( ) > 1.5
def test_pattern(tmp_path: Path, dl1_file, dl1_proton_file): from ctapipe.tools.dl1_merge import MergeTool # touch a random file to test that the pattern does not use it open(dl1_file.parent / "foo.h5", "w").close() # copy to make sure we don't have other files in the dl1 dir disturb this for f in (dl1_file, dl1_proton_file): shutil.copy(f, tmp_path) output = tmp_path / "merged_pattern.dl1.h5" ret = run_tool( tool=MergeTool(), argv=[ "-i", str(tmp_path), "-p", "*.dl1.h5", f"--output={output}", "--overwrite", ], cwd=tmp_path, ) assert ret == 0 run_stage1(output, cwd=tmp_path)
def test_training_from_simtel(tmp_path): """ check we can write both dl1 and dl2 info (e.g. for training input) """ config = Path("./examples/training_config.json").absolute() output = tmp_path / "test_training.DL1DL2.h5" assert ( run_tool( ProcessorTool(), argv=[ f"--config={config}", f"--input={GAMMA_TEST_LARGE}", f"--output={output}", "--max-events=5", "--overwrite", ], cwd=tmp_path, ) == 0 ) # check tables were written with tables.open_file(output, mode="r") as testfile: assert testfile.root.dl1.event.telescope.parameters.tel_002 assert testfile.root.dl2.event.subarray.geometry.HillasReconstructor
def dl1_muon_file(dl1_tmp_path): """ DL1 file containing only images from a muon simulation set. """ from ctapipe.core import run_tool from ctapipe.tools.process import ProcessorTool output = dl1_tmp_path / "muons.dl1.h5" # prevent running process multiple times in case of parallel tests with FileLock(output.with_suffix(output.suffix + ".lock")): if output.is_file(): return output infile = get_dataset_path("lst_muons.simtel.zst") argv = [ f"--input={infile}", f"--output={output}", "--write-images", "--DataWriter.write_parameters=False", "--DataWriter.Contact.name=αℓℓ the äüöß", "--SimTelEventSource.focal_length_choice=nominal", ] assert run_tool(ProcessorTool(), argv=argv, cwd=dl1_tmp_path) == 0 return output