def test_assert_apply_adds_pmt_id_to_hits(self): calib = Calibration(filename=data_path("detx/detx_v1.detx")) hits = Table( {"dom_id": [2, 3, 3], "channel_id": [0, 1, 2], "time": [10.1, 11.2, 12.3]} ) chits = calib.apply(hits, correct_slewing=False) self.assertListEqual([4, 8, 9], list(chits.pmt_id))
def test_apply_to_hits_with_dom_id_and_channel_id_with_wrong_calib_raises(self): calib = Calibration(filename=data_path("detx/detx_v1.detx")) hits = Table({"dom_id": [999], "channel_id": [0], "time": [10.1]}) with self.assertRaises(KeyError): calib.apply(hits, correct_slewing=False)
def test_apply_without_affecting_primary_hit_table(self): calib = Calibration(filename=DETX_FILENAME) hits = Table({'pmt_id': [1, 2, 1], 'time': [10.1, 11.2, 12.3]}) hits_compare = hits.copy() calib.apply(hits) for t_primary, t_calib in zip(hits_compare, hits): self.assertAlmostEqual(t_primary, t_calib)
def test_apply_without_affecting_primary_hit_table(self): calib = Calibration(filename=data_path("detx/detx_v1.detx")) hits = Table({"pmt_id": [1, 2, 1], "time": [10.1, 11.2, 12.3]}) hits_compare = hits.copy() calib.apply(hits, correct_slewing=False) for t_primary, t_calib in zip(hits_compare, hits): self.assertAlmostEqual(t_primary, t_calib)
def test_floors(self): calib = Calibration(filename=data_path("detx/detx_v1.detx")) hits = Table( {"dom_id": [2, 6, 3], "channel_id": [0, 1, 2], "time": [10.1, 11.2, 12.3]} ) floors = calib.floors(hits) assert np.allclose([2, 3, 3], floors)
def test_apply_to_hits_from_km3io(self): calib = Calibration(filename=data_path("detx/km3net_offline.detx")) hits = km3io.OfflineReader(data_path("offline/km3net_offline.root"))[0].hits chits = calib.apply(hits) assert 176 == len(chits.t0) assert np.allclose([207747.825, 207745.656, 207743.836], chits.t0.tolist()[:3]) chits = calib.apply(hits[:3]) assert 3 == len(chits.t0) assert np.allclose([207747.825, 207745.656, 207743.836], chits.t0.tolist()[:3])
def test_apply_to_hits_from_km3io_iterator(self): calib = Calibration(filename=data_path("detx/km3net_offline.detx")) f = km3io.OfflineReader(data_path("offline/km3net_offline.root")) for event in f: chits = calib.apply(event.hits) assert 176 == len(chits.t0) assert np.allclose( [207747.825, 207745.656, 207743.836], chits.t0.tolist()[:3] ) break
def test_apply_to_timeslice_hits(self): tshits = Table.from_template({ 'channel_id': [0, 1, 2], 'dom_id': [2, 3, 3], 'time': [10.1, 11.2, 12.3], 'tot': np.ones(3, dtype=float), 'group_id': 0, }, 'TimesliceHits') calib = Calibration(filename=DETX_FILENAME) c_tshits = calib.apply(tshits) assert len(c_tshits) == len(tshits) assert np.allclose([40, 80, 90], c_tshits.t0) # TimesliceHits is using int4 for times, so it's truncated when we pass in float64 assert np.allclose([50.1, 91.2, 102.3], c_tshits.time, atol=0.1)
def test_apply_to_timeslice_hits(self): tshits = Table.from_template( { "channel_id": [0, 1, 2], "dom_id": [2, 3, 3], "time": [10.1, 11.2, 12.3], "tot": np.ones(3, dtype=float), "group_id": 0, }, "TimesliceHits", ) calib = Calibration(filename=data_path("detx/detx_v1.detx")) c_tshits = calib.apply(tshits, correct_slewing=False) assert len(c_tshits) == len(tshits) assert np.allclose([40, 80, 90], c_tshits.t0) # TimesliceHits is using int4 for times, so it's truncated when we pass in float64 assert np.allclose([50.1, 91.2, 102.3], c_tshits.time, atol=0.1)
def test_apply_to_hits_with_pmt_id_aka_mc_hits(self): calib = Calibration(filename=data_path("detx/detx_v1.detx")) hits = Table({"pmt_id": [1, 2, 1], "time": [10.1, 11.2, 12.3]}) chits = calib.apply(hits, correct_slewing=False) assert len(hits) == len(chits) a_hit = chits[0] self.assertAlmostEqual(1.1, a_hit.pos_x) self.assertAlmostEqual(10, a_hit.t0) self.assertAlmostEqual(10.1, a_hit.time) # t0 should not bei applied a_hit = chits[1] self.assertAlmostEqual(1.4, a_hit.pos_x) self.assertAlmostEqual(20, a_hit.t0) self.assertAlmostEqual(11.2, a_hit.time) # t0 should not be applied
def test_apply_to_hits_with_pmt_id_aka_mc_hits_from_km3io(self): calib = Calibration(filename=data_path("detx/KM3NeT_-00000001_20171212.detx")) f = km3io.OfflineReader( data_path( "offline/mcv6.gsg_nue-CCHEDIS_1e4-1e6GeV.sirene.jte.jchain.aanet.1.root" ) ) for event in f: chits = calib.apply(event.mc_hits) assert 840 == len(chits.t0) assert np.allclose([3, 26, 24, 4, 23, 25], chits.channel_id[:6]) assert np.allclose([3401, 3401, 3406, 3411, 5501, 5501], chits.dom_id[:6]) assert np.allclose([1, 1, 6, 11, 1, 1], chits.floor[:6]) assert np.allclose([34, 34, 34, 34, 55, 55], chits.du[:6]) assert np.allclose( [ 1679.18706571, 1827.14262054, 1926.71722628, 2433.83097585, 1408.35942832, 1296.51397496, ], chits.time[:6], ) assert np.allclose( [2.034, 1.847, 1.938, 2.082, -54.96, -55.034], chits.pos_x[:6] ) assert np.allclose( [-233.415, -233.303, -233.355, -233.333, -341.346, -341.303], chits.pos_y[:6], ) assert np.allclose( [65.059, 64.83, 244.83, 425.111, 64.941, 64.83], chits.pos_z[:6] ) assert np.allclose([4, 4, 4, 26, 4, 4], f.mc_hits.origin[0][:6].tolist()) assert np.allclose( [36835, 36881, 37187, 37457, 60311, 60315], f.mc_hits.pmt_id[0][:6].tolist(), ) break
def test_apply_to_hits_with_pmt_id(self): calib = Calibration(filename=DETX_FILENAME) hits = Table({'pmt_id': [1, 2, 1], 'time': [10.1, 11.2, 12.3]}) chits = calib.apply(hits) assert len(hits) == len(chits) a_hit = chits[0] self.assertAlmostEqual(1.1, a_hit.pos_x) self.assertAlmostEqual(10, a_hit.t0) t0 = a_hit.t0 self.assertAlmostEqual(10.1 + t0, a_hit.time) a_hit = chits[1] self.assertAlmostEqual(1.4, a_hit.pos_x) self.assertAlmostEqual(20, a_hit.t0) t0 = a_hit.t0 self.assertAlmostEqual(11.2 + t0, a_hit.time)
def test_apply_to_hits_with_dom_id_and_channel_id(self): calib = Calibration(filename=data_path("detx/detx_v1.detx")) hits = Table( {"dom_id": [2, 3, 3], "channel_id": [0, 1, 2], "time": [10.1, 11.2, 12.3]} ) chits = calib.apply(hits, correct_slewing=False) assert len(hits) == len(chits) a_hit = chits[0] self.assertAlmostEqual(2.1, a_hit.pos_x) self.assertAlmostEqual(40, a_hit.t0) t0 = a_hit.t0 self.assertAlmostEqual(10.1 + t0, a_hit.time) a_hit = chits[1] self.assertAlmostEqual(3.4, a_hit.pos_x) self.assertAlmostEqual(80, a_hit.t0) t0 = a_hit.t0 self.assertAlmostEqual(11.2 + t0, a_hit.time)
def test_time_slewing_correction(self): calib = Calibration(filename=data_path("detx/detx_v1.detx")) hits = Table( { "dom_id": [2, 3, 3], "channel_id": [0, 1, 2], "time": [10.1, 11.2, 12.3], "tot": [0, 10, 255], } ) chits = calib.apply(hits) # correct_slewing=True is default assert len(hits) == len(chits) a_hit = chits[0] self.assertAlmostEqual(10.1 + a_hit.t0 - slew(a_hit.tot), a_hit.time) a_hit = chits[1] self.assertAlmostEqual(11.2 + a_hit.t0 - slew(a_hit.tot), a_hit.time) a_hit = chits[2] self.assertAlmostEqual(12.3 + a_hit.t0 - slew(a_hit.tot), a_hit.time)
def test_apply_to_hits_with_dom_id_and_channel_id(self): calib = Calibration(filename=DETX_FILENAME) hits = Table({ 'dom_id': [2, 3, 3], 'channel_id': [0, 1, 2], 'time': [10.1, 11.2, 12.3] }) chits = calib.apply(hits) assert len(hits) == len(chits) a_hit = chits[0] self.assertAlmostEqual(2.1, a_hit.pos_x) self.assertAlmostEqual(40, a_hit.t0) t0 = a_hit.t0 self.assertAlmostEqual(10.1 + t0, a_hit.time) a_hit = chits[1] self.assertAlmostEqual(3.4, a_hit.pos_x) self.assertAlmostEqual(80, a_hit.t0) t0 = a_hit.t0 self.assertAlmostEqual(11.2 + t0, a_hit.time)
def test_init_with_detector(self): det = Detector(data_path("detx/detx_v1.detx")) Calibration(detector=det)
def test_init_with_det_id(self, mock_detector): Calibration(det_id=1) mock_detector.assert_called_with(t0set=None, calibset=None, det_id=1) Calibration(det_id=1, calibset=2, t0set=3) mock_detector.assert_called_with(t0set=3, calibset=2, det_id=1)
def test_init_with_filename(self, mock_detector): Calibration(filename="foo.detx") mock_detector.assert_called_with(filename="foo.detx")
def test_init_with_wrong_file_extension(self): with self.assertRaises(NotImplementedError): Calibration(filename="foo")
def __init__(self, detector_file=None, event_file=None, min_tot=None, skip_to_blob=0, width=1000, height=700, x=50, y=50): self.camera = Camera() self.camera.is_rotating = True self.colourist = Colourist() current_path = os.path.dirname(os.path.abspath(__file__)) if not detector_file: filepath = 'data/km3net_jul13_90m_r1494_corrected.detx' detector_file = os.path.join(current_path, filepath) self.load_logo() self.init_opengl(width=width, height=height, x=x, y=y) print("OpenGL Version: {0}".format(glGetString(GL_VERSION))) self.clock = Clock(speed=100) self.timer = Clock(snooze_interval=1 / 30) self.frame_index = 0 self.event_index = skip_to_blob self.is_recording = False self.min_tot = min_tot self.time_offset = 0 VERTEX_SHADER = compileShader( """ void main() { gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; }""", GL_VERTEX_SHADER) FRAGMENT_SHADER = compileShader( """ void main() { gl_FragColor = vec4(0.5, 0.5, 0.5, 1); }""", GL_FRAGMENT_SHADER) self.shader = compileProgram(VERTEX_SHADER, FRAGMENT_SHADER) self.blob = None self.objects = {} self.shaded_objects = [] self.mouse_x = None self.mouse_y = None self.show_secondaries = True self.show_help = False self._help_string = None self.show_info = True self.spectrum = None self.current_spectrum = 'default' self.cmap = self.colourist.default_cmap self.min_hit_time = None self.max_hit_time = None if detector_file.endswith('.detx'): self.detector = Detector(filename=detector_file) self.geometry = Calibration(filename=detector_file) else: self.detector = Detector(det_id=detector_file) self.geometry = Calibration(det_id=detector_file) dom_pos = self.detector.dom_positions.values() min_z = min([z for x, y, z in dom_pos]) max_z = max([z for x, y, z in dom_pos]) z_shift = (max_z - min_z) / 2 self.dom_positions = np.array([tuple(pos) for pos in dom_pos], 'f') self.camera.target = Vec3(0, 0, z_shift) self.dom_positions_vbo = vbo.VBO(self.dom_positions) if event_file: self.pump = GenericPump(event_file) try: self.load_blob(skip_to_blob) except IndexError: print("Could not load blob at index {0}".format(skip_to_blob)) print("Starting from the first one...") self.load_blob(0) else: print("No event file specified. Only the detector will be shown.") self.clock.reset() self.timer.reset() glutMainLoop()
class RainbowAlga(object): def __init__(self, detector_file=None, event_file=None, min_tot=None, skip_to_blob=0, width=1000, height=700, x=50, y=50): self.camera = Camera() self.camera.is_rotating = True self.colourist = Colourist() current_path = os.path.dirname(os.path.abspath(__file__)) if not detector_file: filepath = 'data/km3net_jul13_90m_r1494_corrected.detx' detector_file = os.path.join(current_path, filepath) self.load_logo() self.init_opengl(width=width, height=height, x=x, y=y) print("OpenGL Version: {0}".format(glGetString(GL_VERSION))) self.clock = Clock(speed=100) self.timer = Clock(snooze_interval=1 / 30) self.frame_index = 0 self.event_index = skip_to_blob self.is_recording = False self.min_tot = min_tot self.time_offset = 0 VERTEX_SHADER = compileShader( """ void main() { gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; }""", GL_VERTEX_SHADER) FRAGMENT_SHADER = compileShader( """ void main() { gl_FragColor = vec4(0.5, 0.5, 0.5, 1); }""", GL_FRAGMENT_SHADER) self.shader = compileProgram(VERTEX_SHADER, FRAGMENT_SHADER) self.blob = None self.objects = {} self.shaded_objects = [] self.mouse_x = None self.mouse_y = None self.show_secondaries = True self.show_help = False self._help_string = None self.show_info = True self.spectrum = None self.current_spectrum = 'default' self.cmap = self.colourist.default_cmap self.min_hit_time = None self.max_hit_time = None if detector_file.endswith('.detx'): self.detector = Detector(filename=detector_file) self.geometry = Calibration(filename=detector_file) else: self.detector = Detector(det_id=detector_file) self.geometry = Calibration(det_id=detector_file) dom_pos = self.detector.dom_positions.values() min_z = min([z for x, y, z in dom_pos]) max_z = max([z for x, y, z in dom_pos]) z_shift = (max_z - min_z) / 2 self.dom_positions = np.array([tuple(pos) for pos in dom_pos], 'f') self.camera.target = Vec3(0, 0, z_shift) self.dom_positions_vbo = vbo.VBO(self.dom_positions) if event_file: self.pump = GenericPump(event_file) try: self.load_blob(skip_to_blob) except IndexError: print("Could not load blob at index {0}".format(skip_to_blob)) print("Starting from the first one...") self.load_blob(0) else: print("No event file specified. Only the detector will be shown.") self.clock.reset() self.timer.reset() glutMainLoop() def load_logo(self): if self.colourist.print_mode: image = 'images/km3net_logo_print.bmp' else: image = 'images/km3net_logo.bmp' current_path = os.path.dirname(os.path.abspath(__file__)) image_path = os.path.join(current_path, image) self.logo = Image.open(image_path) # Create a raw string from the image data - data will be unsigned bytes # RGBpad, no stride (0), and first line is top of image (-1) self.logo_bytes = self.logo.tobytes("raw", "RGB", 0, -1) def load_blob(self, index=0): print("Loading blob {0}...".format(index)) blob = self.blob = self.pump.get_blob(index) self.objects = {} self.shaded_objects = [] self.time_offset = 0 try: self.add_neutrino(blob) except TypeError: pass self.add_mc_tracks(blob) self.add_reco_tracks(blob) self.initialise_spectrum(blob, style=self.current_spectrum) def reload_blob(self): self.load_blob(self.event_index) def initialise_spectrum(self, blob, style="default"): if style == 'default': hits = self.extract_hits(blob) if hits is None: return hits = self.remove_hidden_hits(hits) hit_times = hits.time if len(hit_times) == 0: log.warn("No hits left after applying cuts.") return self.min_hit_time = min(hit_times) self.max_hit_time = max(hit_times) self.time_offset = self.min_hit_time self.clock._global_offset = self.min_hit_time / self.clock.speed def spectrum(time, hit=None): min_time = self.min_hit_time max_time = self.max_hit_time diff = max_time - min_time one_percent = diff / 100 try: progress = (time - min_time) / one_percent / 100 except ZeroDivisionError: progress = 0 return tuple(self.cmap(progress))[:3] self.spectrum = spectrum if style in [ 'time_residuals_point_source', 'time_residuals_cherenkov_cone' ]: try: track_ins = blob['McTracks'] except KeyError: log.error("No tracks found to determine Cherenkov parameters!") self.current_spectrum = "default" return # most_energetic_muon = max(track_ins, key=lambda t: t.E) muon_pos = np.mean(track_ins.pos) muon_dir = track_ins.dir[0] # if not pdg2name(most_energetic_muon.particle_type) \ # in ['mu-', 'mu+']: # log.error("No muon found to determine Cherenkov parameters!") # self.current_spectrum = "default" # return hits = self.extract_hits(blob) if hits is None: return hits = self.first_om_hits(hits) def cherenkov_time(pmt_pos): """Calculates Cherenkov arrival time in [ns]""" v = pmt_pos - muon_pos l = v.dot(muon_dir) k = np.sqrt(v.dot(v) - l**2) v_g = constants.c_water_km3net theta = constants.theta_cherenkov_water_km3net a_1 = k / np.tan(theta) a_2 = k / np.sin(theta) t_c = 1 / constants.c * (l - a_1) + 1 / v_g * a_2 return t_c * 1e9 def point_source_time(pmt_pos): """Calculates cherenkov arrival time with cascade hypothesis""" vertex_pos = blob['Neutrino'].pos v = pmt_pos - vertex_pos v = np.sqrt(v.dot(v)) v_g = constants.c_water_antares t_c = v / v_g return t_c * 1e9 + blob['Neutrino'].time self.min_hit_time = -100 self.max_hit_time = 100 def spectrum(time, hit=None): if hit: pmt_pos = self._get_pmt_pos_from_hit(hit) if not hit.t_cherenkov: if style == 'time_residuals_point_source': t_c = point_source_time(pmt_pos) elif style == 'time_residuals_cherenkov_cone': t_c = cherenkov_time(pmt_pos) hit.t_cherenkov = t_c log.debug("Hit time: {0}, Expected: {1}, " "Time Residual: {2}".format( time, t_c, time - t_c)) time = time - hit.t_cherenkov diff = self.max_hit_time - self.min_hit_time one_percent = diff / 100 try: progress = (time - self.min_hit_time) / one_percent / 100 if progress > 1: progress = 1 except ZeroDivisionError: progress = 0 return tuple(self.cmap(progress))[:3] self.spectrum = spectrum def toggle_spectrum(self): if self.current_spectrum == 'default': print('cherenkov') self.current_spectrum = 'time_residuals_cherenkov_cone' elif self.current_spectrum == 'time_residuals_cherenkov_cone': print('cherenkov') self.current_spectrum = 'time_residuals_point_source' else: print('default') self.current_spectrum = 'default' self.reload_blob() def remove_hidden_hits(self, hits): log.debug("Skipping removing hidden hits") for hit in hits: rb_hit = Hit(hit.pos_x, hit.pos_y, hit.pos_z, hit.time, 0, 0, hit.tot) self.shaded_objects.append(rb_hit) return hits log.debug("Removing hidden hits") om_hit_map = {} om_combs = set(zip(hits.du, hits.floor)) for om_comb in om_combs: du, floor = om_comb om_hit_map[om_comb] = hits[(hits.du == du) & (hits.floor == floor)] print(om_hit_map) for hit in hits: x, y, z = hit.pos_x, hit.pos_y, hit.pos_z rb_hit = Hit(x, y, z, hit.time, hit.pmt_id, hit.id, hit.tot) om_hit_map.setdefault(line_floor, []).append(rb_hit) hits = [] for om, om_hits in om_hit_map.items(): largest_hit = None for hit in om_hits: if largest_hit: if hit.tot > largest_hit.tot: hidden_hits = om_hits[:om_hits.index(hit)] hit.replaces_hits = hidden_hits hits.append(hit) self.shaded_objects.append(hit) largest_hit = hit else: hits.append(hit) self.shaded_objects.append(hit) largest_hit = hit print("Number of hits after removing hidden ones: {0}".format( len(hits))) return hits def first_om_hits(self, hits): log.debug("Entering first_om_hits()") print(hits.time) om_hit_map = {} for hit in hits: if hit.time < 0: continue x, y, z = self._get_pmt_pos_from_hit(hit) rb_hit = Hit(x, y, z, hit.time, hit.pmt_id, hit.id, hit.tot) try: # EVT file line_floor = self.detector.pmtid2omkey(hit.pmt_id)[:2] except KeyError: # Other files line, floor, _ = self.detector.doms[hit.dom_id] line_floor = line, floor om_hit_map.setdefault(line_floor, []).append(rb_hit) hits = [] for om, om_hits in om_hit_map.items(): first_hit = om_hits[0] self.shaded_objects.append(first_hit) hits.append(first_hit) print("Number of first OM hits: {0}".format(len(hits))) return hits def extract_hits(self, blob): log.debug("Entering extract_hits()") if 'Hits' not in blob: log.error("No hits found in the blob!") return print(blob['Hits']) hits = self.geometry.apply(blob['Hits']) print("Number of hits: {0}".format(len(hits))) if self.min_tot: hits = hits[hits.tot > self.min_tot] print("Number of hits after ToT={0} cut: {1}".format( self.min_tot, len(hits))) if not self.min_tot and len(hits) > 500: print("Warning: consider applying a ToT filter to reduce the " "amount of hits, according to your graphic cards " "performance!") if len(hits) == 0: log.warning("No hits remaining after applying the ToT cut") return return hits.sorted(by='time') def add_neutrino(self, blob): """Add the neutrino to the scene.""" if 'Neutrino' not in blob: return print(neutrino) pos = neutrino.pos particle = Neutrino(pos[0], pos[1], pos[2], neutrino.dir.x, neutrino.dir.y, neutrino.dir.z, 0) particle.color = (1.0, 0.0, 0.0) particle.line_width = 3 self.objects.setdefault("neutrinos", []).append(particle) def add_mc_tracks(self, blob): """Find MC particles and add them to the objects to render.""" try: track_ins = blob['McTracks'] except KeyError: print("No MCTracks found.") return event_info = blob['EventInfo'] timestamp_in_ns = event_info.timestamp * 1e9 + event_info.nanoseconds from km3modules.mc import convert_mc_times_to_jte_times time_converter = np.frompyfunc(convert_mc_times_to_jte_times, 3, 1) track_ins['time'] = time_converter(track_ins.time, timestamp_in_ns, event_info.mc_time) # print(track_ins) # try: # highest_energetic_track = max(track_ins, key=lambda t: t.E) # # highest_energy = highest_energetic_track.E # except AttributeError: # hdf5 mc tracks are not implemented yet # highest_energetic_track = max(track_ins, key=lambda t: t.energy) # # highest_energy = highest_energetic_track.energy for track in track_ins: particle_type = track.type energy = track.energy track_length = np.abs(track.length) print("Track length: {0}".format(track_length)) if particle_type in (0, 22): # skip unknowns, photons continue # if angle_between(highest_energetic_track.dir, track.dir) > 0.035: # # TODO: make this realistic! # # skip if angle too large # continue # # if particle_type not in (-11, 11, -13, 13, -15, 15): # # # TODO: make this realistic! # # track_length = 200 * energy / highest_energy particle = Particle( track.pos_x, track.pos_y, track.pos_z, track.dir_x, track.dir_y, track.dir_z, track.time, constants.c, self.colourist, energy, length=track_length) particle.hidden = not self.show_secondaries # if track.id == highest_energetic_track.id: # particle.color = (0.0, 1.0, 0.2) # particle.line_width = 3 # particle.cherenkov_cone_enabled = True # particle.hidden = False self.objects.setdefault("mc_tracks", []).append(particle) def add_reco_tracks(self, blob): """Find reco particles and add them to the objects to render.""" pass # try: # reco = blob['RecoTrack'] # except (KeyError, TypeError): # return # particle = ParticleFit(track.pos.x, track.pos.y, track.pos.z, # track.dir.x, track.dir.y, track.dir.z, # constants.c, track.ts, track.te) # dir = Direction((-0.05529533412, -0.1863083737, -0.9809340528)) # pos = Position(( 128.9671546, 135.4618441, 397.8256624)) # self.camera.target = Position(( 128.9671546, 135.4618441, 397.8256624)) # # pos.z += 405.93 # offset = 0 # pos = pos + offset*dir # t_offset = offset / constants.c_water_km3net * 1e9 # #t_0 = 86355000.1 - t_offset # t_0 = 86358182.1 # print(t_offset) # print(t_0) # print(constants.c) # particle = Particle(pos.x, pos.y, pos.z, # dir.x, dir.y, dir.z, t_0, # constants.c, self.colourist, 1e4) # # particle.cherenkov_cone_enabled = True # particle.hidden = False # particle.line_width = 3 # self.objects.setdefault("reco_tracks", []).append(particle) def toggle_secondaries(self): self.show_secondaries = not self.show_secondaries secondaries = self.objects["mc_tracks"] for secondary in secondaries: secondary.hidden = not self.show_secondaries highest_energetic = max(secondaries, key=lambda s: s.energy) if highest_energetic: highest_energetic.hidden = False def load_next_blob(self): print("Loading next blob") try: self.load_blob(self.event_index + 1) except IndexError: return else: self.clock.reset() self.event_index += 1 def load_previous_blob(self): try: self.load_blob(self.event_index - 1) except IndexError: return else: self.clock.reset() self.event_index -= 1 def init_opengl(self, width, height, x, y): glutInit() glutInitWindowPosition(x, y) glutInitWindowSize(width, height) glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_MULTISAMPLE) glutCreateWindow("Rainbow Alga") glutDisplayFunc(self.render) glutIdleFunc(self.render) glutReshapeFunc(self.resize) glutMouseFunc(self.mouse) glutMotionFunc(self.drag) glutKeyboardFunc(self.keyboard) glutSpecialFunc(self.special_keyboard) glClearDepth(1.0) glClearColor(0.0, 0.0, 0.0, 0.0) glMatrixMode(GL_PROJECTION) glLoadIdentity() glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 3000) glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT) # Lighting light_ambient = (0.0, 0.0, 0.0, 1.0) light_diffuse = (1.0, 1.0, 1.0, 1.0) light_specular = (1.0, 1.0, 1.0, 1.0) light_position = (-100.0, 100.0, 100.0, 0.0) mat_ambient = (0.7, 0.7, 0.7, 1.0) mat_diffuse = (0.8, 0.8, 0.8, 1.0) mat_specular = (1.0, 1.0, 1.0, 1.0) high_shininess = (100) glEnable(GL_LIGHT0) glEnable(GL_NORMALIZE) glEnable(GL_COLOR_MATERIAL) glEnable(GL_LIGHTING) glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient) glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse) glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular) glLightfv(GL_LIGHT0, GL_POSITION, light_position) glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient) glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse) glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular) glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess) # Transparency glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) def render(self): self.clock.record_frame_time() if self.is_recording and not self.timer.is_snoozed: self.frame_index += 1 frame_name = "Frame_{0:05d}.jpg".format(self.frame_index) self.save_screenshot(frame_name) self.timer.snooze() glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) self.colourist.now_background() if self.camera.is_rotating: self.camera.rotate_z(0.2) self.camera.look() self.draw_detector() glEnable(GL_DEPTH_TEST) glEnable(GL_LINE_SMOOTH) glShadeModel(GL_FLAT) glEnable(GL_LIGHTING) for obj in self.shaded_objects: obj.draw(self.clock.time, self.spectrum) glDisable(GL_LIGHTING) for obj in itertools.chain.from_iterable(self.objects.values()): obj.draw(self.clock.time) self.draw_gui() glutSwapBuffers() def draw_detector(self): glUseProgram(self.shader) try: self.dom_positions_vbo.bind() try: glEnableClientState(GL_VERTEX_ARRAY) glVertexPointerf(self.dom_positions_vbo) glPointSize(2) glDrawArrays(GL_POINTS, 0, len(self.dom_positions) * 3) finally: self.dom_positions_vbo.unbind() glDisableClientState(GL_VERTEX_ARRAY) finally: glUseProgram(0) def draw_gui(self): logo = self.logo logo_bytes = self.logo_bytes width = glutGet(GLUT_WINDOW_WIDTH) height = glutGet(GLUT_WINDOW_HEIGHT) glMatrixMode(GL_PROJECTION) glPushMatrix() glLoadIdentity() glOrtho(0.0, width, height, 0.0, -1.0, 10.0) glMatrixMode(GL_MODELVIEW) glLoadIdentity() glShadeModel(GL_SMOOTH) glClear(GL_DEPTH_BUFFER_BIT) try: self.draw_colour_legend() except TypeError: pass glPushMatrix() glLoadIdentity() glRasterPos(4, logo.size[1] + 4) glDrawPixels(logo.size[0], logo.size[1], GL_RGB, GL_UNSIGNED_BYTE, logo_bytes) glPopMatrix() glMatrixMode(GL_PROJECTION) glPopMatrix() glMatrixMode(GL_MODELVIEW) self.colourist.now_text() if self.show_help: self.display_help() if self.show_info: self.display_info() def draw_colour_legend(self): menubar_height = self.logo.size[1] + 4 width = glutGet(GLUT_WINDOW_WIDTH) height = glutGet(GLUT_WINDOW_HEIGHT) # Colour legend left_x = width - 20 right_x = width - 10 min_y = menubar_height + 5 max_y = height - 20 time_step_size = math.ceil( (self.max_hit_time - self.min_hit_time) / 20 / 50) * 50 hit_times = list( range( int(self.min_hit_time), int(self.max_hit_time), int(time_step_size))) if len(hit_times) > 1: segment_height = int((max_y - min_y) / len(hit_times)) glMatrixMode(GL_MODELVIEW) glLoadIdentity() glDisable(GL_LIGHTING) glBegin(GL_QUADS) for hit_time in hit_times: segment_nr = hit_times.index(hit_time) glColor3f(*self.spectrum(hit_time)) glVertex2f(left_x, max_y - segment_height * segment_nr) glVertex2f(right_x, max_y - segment_height * segment_nr) glColor3f(*self.spectrum(hit_time + time_step_size)) glVertex2f(left_x, max_y - segment_height * (segment_nr + 1)) glVertex2f(right_x, max_y - segment_height * (segment_nr + 1)) glEnd() # Colour legend labels self.colourist.now_text() for hit_time in hit_times: segment_nr = hit_times.index(hit_time) draw_text_2d( "{0:>5}ns".format(int(hit_time - self.time_offset)), width - 80, (height - max_y) + segment_height * segment_nr) def resize(self, width, height): if width < 400: glutReshapeWindow(400, height) if height < 300: glutReshapeWindow(width, 300) if height == 0: height = 1 glViewport(0, 0, width, height) glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective(45.0, float(width) / float(height), 0.1, 10000.0) glMatrixMode(GL_MODELVIEW) def mouse(self, button, state, x, y): width = glutGet(GLUT_WINDOW_WIDTH) if button == GLUT_LEFT_BUTTON: if state == GLUT_DOWN: if x > width - 70: self.drag_mode = 'spectrum' else: self.drag_mode = 'rotate' self.camera.is_rotating = False self.mouse_x = x self.mouse_y = y if state == GLUT_UP: self.drag_mode = None if button == 3: self.camera.distance = self.camera.distance + 2 if button == 4: self.camera.distance = self.camera.distance - 2 def keyboard(self, key, x, y): log.debug("Key {} pressed".format(key)) if (key == b"r"): self.clock.reset() if (key == b"h"): self.show_help = not self.show_help if (key == b'i'): self.show_info = not self.show_info if (key == b"+"): self.camera.distance = self.camera.distance - 50 if (key == b"-"): self.camera.distance = self.camera.distance + 50 if (key == b"."): self.min_tot += 0.5 self.reload_blob() if (key == b","): self.min_tot -= 0.5 self.reload_blob() if (key == b'n'): self.load_next_blob() if (key == b'p'): self.load_previous_blob() if (key == b'u'): self.toggle_secondaries() if (key == b't'): self.toggle_spectrum() if (key == b'x'): self.cmap = self.colourist.next_cmap if (key == b'm'): self.colourist.print_mode = not self.colourist.print_mode self.load_logo() if (key == b'a'): self.camera.is_rotating = not self.camera.is_rotating if (key == b'c'): self.colourist.cherenkov_cone_enabled = \ not self.colourist.cherenkov_cone_enabled if (key == b"s"): event_number = self.blob['start_event'][0] try: neutrino = self.blob['Neutrino'] except KeyError: neutrino_str = '' else: neutrino_str = str(neutrino).replace(' ', '_').replace(',', '') neutrino_str = neutrino_str.replace('Neutrino:', '') screenshot_name = "RA_Event{0}_ToTCut{1}{2}_t{3}ns.png".format( event_number, self.min_tot, neutrino_str, int(self.clock.time)) self.save_screenshot(screenshot_name) if (key == b'v'): self.frame_index = 0 self.is_recording = not self.is_recording if (key == b" "): if self.clock.is_paused: self.clock.resume() else: self.clock.pause() if (key in (b'q', b'\x1b')): raise SystemExit def special_keyboard(self, key, x, z): if key == GLUT_KEY_LEFT: self.clock.rewind(300) if key == GLUT_KEY_RIGHT: self.clock.fast_forward(300) def drag(self, x, y): if self.drag_mode == 'rotate': self.camera.rotate_z(self.mouse_x - x) self.camera.move_z(-(self.mouse_y - y) * 8) if self.drag_mode == 'spectrum': self.min_hit_time += (self.mouse_y - y) * 10 self.max_hit_time += (self.mouse_y - y) * 10 self.max_hit_time -= (self.mouse_x - x) * 10 self.min_hit_time += (self.mouse_x - x) * 10 self.min_hit_time = base_round(self.min_hit_time, 10) self.max_hit_time = base_round(self.max_hit_time, 10) self.mouse_x = x self.mouse_y = y def save_screenshot(self, name='screenshot.png'): width = glutGet(GLUT_WINDOW_WIDTH) height = glutGet(GLUT_WINDOW_HEIGHT) pixelset = (GLubyte * (3 * width * height))(0) glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixelset) image = Image.frombytes( mode="RGB", size=(width, height), data=pixelset) image = image.transpose(Image.FLIP_TOP_BOTTOM) image.save(name) print("Screenshot saved as '{0}'.".format(name)) @property def help_string(self): if not self._help_string: options = { 'h': 'help', 'i': 'show event info', 'n': 'next event', 'p': 'previous event', 'LEFT': '+100ns', 'RIGHT': '-100ns', 'a': 'enable/disable rotation animation', 'c': 'enable/disable Cherenkov cone', 't': 'toggle between spectra', 'u': 'toggle secondaries', 'x': 'cycle through colour schemes', 'm': 'toggle screen/print mode', 's': 'save screenshot (screenshot.png)', 'v': 'start/stop recording (Frame_XXXXX.jpg)', 'r': 'reset time', '<space>': 'pause time', '+ or -': 'zoom in/out', ', or .': 'decrease/increase min_tot by 0.5ns', '<esc> or q': 'quit', } help_string = "Keyboard commands:\n-------------------\n" for key in sorted(options.keys()): help_string += "{key:>10} : {description}\n" \ .format(key=key, description=options[key]) self._help_string = help_string return self._help_string @property def blob_info(self): if not self.blob: return '' info_text = '' if 'start_event' in self.blob: event_number = self.blob['start_event'][0] info_text += "Event #{0}, ToT>{1}ns\n" \ .format(event_number, self.min_tot) if 'Neutrion' in self.blob: neutrino = self.blob['Neutrino'] info_text += str(neutrino) return info_text def display_help(self): pos_y = glutGet(GLUT_WINDOW_HEIGHT) - 80 draw_text_2d(self.help_string, 10, pos_y) def display_info(self): draw_text_2d( "FPS: {0:.1f}\nTime: {1:.0f} (+{2:.0f}) ns".format( self.clock.fps, self.clock.time - self.time_offset, self.time_offset), 10, 30) draw_text_2d(self.blob_info, 150, 30)
import matplotlib.ticker as ticker import matplotlib.dates as md import numpy as np from km3pipe import Pipeline, Module from km3pipe.calib import Calibration from km3pipe.io import CHPump from km3pipe.io.daq import DAQProcessor import km3pipe.style km3pipe.style.use('km3pipe') PLOTS_PATH = 'www/plots' N_DOMS = 18 N_DUS = 2 cal = Calibration(det_id=14) detector = cal.detector xfmt = md.DateFormatter('%Y-%m-%d %H:%M') lock = threading.Lock() class ZTPlot(Module): def configure(self): self.run = True self.max_queue = 3 self.queue = Queue() self.thread = threading.Thread(target=self.plot).start() def process(self, blob): if 'Hits' not in blob:
def test_assert_apply_adds_dom_id_and_channel_id_to_mc_hits(self): calib = Calibration(filename=data_path("detx/detx_v1.detx")) hits = Table({"pmt_id": [1, 2, 1], "time": [10.1, 11.2, 12.3]}) chits = calib.apply(hits) self.assertListEqual([1, 1, 1], list(chits.dom_id)) self.assertListEqual([0, 1, 0], list(chits.channel_id))