gondola 0.11.7__tar.gz → 0.12.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. {gondola-0.11.7 → gondola-0.12.0}/Cargo.lock +1 -1
  2. {gondola-0.11.7 → gondola-0.12.0}/Cargo.toml +1 -1
  3. {gondola-0.11.7 → gondola-0.12.0}/PKG-INFO +1 -1
  4. gondola-0.12.0/publish_to_bluejay.sh +4 -0
  5. {gondola-0.11.7 → gondola-0.12.0}/python/gondola/visual/tof.py +495 -4
  6. {gondola-0.11.7 → gondola-0.12.0}/src/calibration/tof.rs +2 -1
  7. {gondola-0.11.7 → gondola-0.12.0}/src/events/rb_waveform.rs +11 -2
  8. {gondola-0.11.7 → gondola-0.12.0}/src/events/tof_event.rs +2 -4
  9. {gondola-0.11.7 → gondola-0.12.0}/src/events/tof_hit.rs +2 -2
  10. {gondola-0.11.7 → gondola-0.12.0}/src/events.rs +5 -0
  11. {gondola-0.11.7 → gondola-0.12.0}/src/io/parsers.rs +1 -1
  12. {gondola-0.11.7 → gondola-0.12.0}/src/lib.rs +1 -0
  13. {gondola-0.11.7 → gondola-0.12.0}/src/monitoring/cpu_moni_data.rs +20 -42
  14. {gondola-0.11.7 → gondola-0.12.0}/src/monitoring/heartbeats/data_sink_hb.rs +22 -43
  15. {gondola-0.11.7 → gondola-0.12.0}/src/monitoring/heartbeats/event_builder_hb.rs +17 -56
  16. {gondola-0.11.7 → gondola-0.12.0}/src/monitoring/heartbeats/master_trigger_hb.rs +20 -46
  17. {gondola-0.11.7 → gondola-0.12.0}/src/monitoring/ltb_moni_data.rs +16 -41
  18. {gondola-0.11.7 → gondola-0.12.0}/src/monitoring/mtb_moni_data.rs +21 -2
  19. {gondola-0.11.7 → gondola-0.12.0}/src/monitoring/pa_moni_data.rs +13 -1
  20. {gondola-0.11.7 → gondola-0.12.0}/src/monitoring/pb_moni_data.rs +19 -41
  21. {gondola-0.11.7 → gondola-0.12.0}/src/monitoring/rb_moni_data.rs +23 -43
  22. {gondola-0.11.7 → gondola-0.12.0}/src/monitoring.rs +94 -48
  23. {gondola-0.11.7 → gondola-0.12.0}/src/packets/tof_packet.rs +6 -0
  24. {gondola-0.11.7 → gondola-0.12.0}/src/python.rs +16 -2
  25. {gondola-0.11.7 → gondola-0.12.0}/src/stats.rs +1 -1
  26. {gondola-0.11.7 → gondola-0.12.0}/src/tof/algorithms.rs +6 -6
  27. {gondola-0.11.7 → gondola-0.12.0}/src/tof/master_trigger.rs +3 -1
  28. {gondola-0.11.7 → gondola-0.12.0}/.gitignore +0 -0
  29. {gondola-0.11.7 → gondola-0.12.0}/README.md +0 -0
  30. {gondola-0.11.7 → gondola-0.12.0}/alert-manifest-test.toml +0 -0
  31. {gondola-0.11.7 → gondola-0.12.0}/benches/bench.rs +0 -0
  32. {gondola-0.11.7 → gondola-0.12.0}/diesel.toml +0 -0
  33. {gondola-0.11.7 → gondola-0.12.0}/pyproject.toml +0 -0
  34. {gondola-0.11.7 → gondola-0.12.0}/python/gondola/__init__.py +0 -0
  35. {gondola-0.11.7 → gondola-0.12.0}/python/gondola/calibration.py +0 -0
  36. {gondola-0.11.7 → gondola-0.12.0}/python/gondola/db.py +0 -0
  37. {gondola-0.11.7 → gondola-0.12.0}/python/gondola/gaps_flight.db +0 -0
  38. {gondola-0.11.7 → gondola-0.12.0}/python/gondola/io/__init__.py +0 -0
  39. {gondola-0.11.7 → gondola-0.12.0}/python/gondola/reconstruction/__init__.py +0 -0
  40. {gondola-0.11.7 → gondola-0.12.0}/python/gondola/tof/__init__.py +0 -0
  41. {gondola-0.11.7 → gondola-0.12.0}/python/gondola/tof/analysis.py +0 -0
  42. {gondola-0.11.7 → gondola-0.12.0}/python/gondola/tracker/__init__.py +0 -0
  43. {gondola-0.11.7 → gondola-0.12.0}/python/gondola/tracker/analysis.py +0 -0
  44. {gondola-0.11.7 → gondola-0.12.0}/python/gondola/visual/__init__.py +0 -0
  45. {gondola-0.11.7 → gondola-0.12.0}/python/gondola/visual/tracker.py +0 -0
  46. {gondola-0.11.7 → gondola-0.12.0}/src/calibration/tracker.rs +0 -0
  47. {gondola-0.11.7 → gondola-0.12.0}/src/calibration.rs +0 -0
  48. {gondola-0.11.7 → gondola-0.12.0}/src/constants.rs +0 -0
  49. {gondola-0.11.7 → gondola-0.12.0}/src/database/schema.rs +0 -0
  50. {gondola-0.11.7 → gondola-0.12.0}/src/database.rs +0 -0
  51. {gondola-0.11.7 → gondola-0.12.0}/src/errors.rs +0 -0
  52. {gondola-0.11.7 → gondola-0.12.0}/src/events/rb_event.rs +0 -0
  53. {gondola-0.11.7 → gondola-0.12.0}/src/events/rb_event_header.rs +0 -0
  54. {gondola-0.11.7 → gondola-0.12.0}/src/events/telemetry_event.rs +0 -0
  55. {gondola-0.11.7 → gondola-0.12.0}/src/events/tracker_hit.rs +0 -0
  56. {gondola-0.11.7 → gondola-0.12.0}/src/io/caraspace/frame.rs +0 -0
  57. {gondola-0.11.7 → gondola-0.12.0}/src/io/caraspace/reader.rs +0 -0
  58. {gondola-0.11.7 → gondola-0.12.0}/src/io/caraspace/socket_reader.rs +0 -0
  59. {gondola-0.11.7 → gondola-0.12.0}/src/io/caraspace/writer.rs +0 -0
  60. {gondola-0.11.7 → gondola-0.12.0}/src/io/caraspace.rs +0 -0
  61. {gondola-0.11.7 → gondola-0.12.0}/src/io/data_source.rs +0 -0
  62. {gondola-0.11.7 → gondola-0.12.0}/src/io/ipbus.rs +0 -0
  63. {gondola-0.11.7 → gondola-0.12.0}/src/io/root_reader.rs +0 -0
  64. {gondola-0.11.7 → gondola-0.12.0}/src/io/serialization.rs +0 -0
  65. {gondola-0.11.7 → gondola-0.12.0}/src/io/streamers.rs +0 -0
  66. {gondola-0.11.7 → gondola-0.12.0}/src/io/telemetry_reader.rs +0 -0
  67. {gondola-0.11.7 → gondola-0.12.0}/src/io/tof_reader.rs +0 -0
  68. {gondola-0.11.7 → gondola-0.12.0}/src/io/tof_writer.rs +0 -0
  69. {gondola-0.11.7 → gondola-0.12.0}/src/io.rs +0 -0
  70. {gondola-0.11.7 → gondola-0.12.0}/src/monitoring/heartbeats.rs +0 -0
  71. {gondola-0.11.7 → gondola-0.12.0}/src/monitoring/run_statistics.rs +0 -0
  72. {gondola-0.11.7 → gondola-0.12.0}/src/packets/bfsw_ack_packet.rs +0 -0
  73. {gondola-0.11.7 → gondola-0.12.0}/src/packets/gps_packet.rs +0 -0
  74. {gondola-0.11.7 → gondola-0.12.0}/src/packets/magnetometer.rs +0 -0
  75. {gondola-0.11.7 → gondola-0.12.0}/src/packets/telemetry_packet.rs +0 -0
  76. {gondola-0.11.7 → gondola-0.12.0}/src/packets/telemetry_packet_header.rs +0 -0
  77. {gondola-0.11.7 → gondola-0.12.0}/src/packets/telemetry_packet_type.rs +0 -0
  78. {gondola-0.11.7 → gondola-0.12.0}/src/packets/tof_packet_type.rs +0 -0
  79. {gondola-0.11.7 → gondola-0.12.0}/src/packets/tracker.rs +0 -0
  80. {gondola-0.11.7 → gondola-0.12.0}/src/packets/tracker_header.rs +0 -0
  81. {gondola-0.11.7 → gondola-0.12.0}/src/packets.rs +0 -0
  82. {gondola-0.11.7 → gondola-0.12.0}/src/prelude.rs +0 -0
  83. {gondola-0.11.7 → gondola-0.12.0}/src/random.rs +0 -0
  84. {gondola-0.11.7 → gondola-0.12.0}/src/tof/alerts.rs +0 -0
  85. {gondola-0.11.7 → gondola-0.12.0}/src/tof/analysis.rs +0 -0
  86. {gondola-0.11.7 → gondola-0.12.0}/src/tof/analysis_engine.rs +0 -0
  87. {gondola-0.11.7 → gondola-0.12.0}/src/tof/commands.rs +0 -0
  88. {gondola-0.11.7 → gondola-0.12.0}/src/tof/config.rs +0 -0
  89. {gondola-0.11.7 → gondola-0.12.0}/src/tof/cuts.rs +0 -0
  90. {gondola-0.11.7 → gondola-0.12.0}/src/tof/detector_status.rs +0 -0
  91. {gondola-0.11.7 → gondola-0.12.0}/src/tof/master_trigger/control.rs +0 -0
  92. {gondola-0.11.7 → gondola-0.12.0}/src/tof/master_trigger/registers.rs +0 -0
  93. {gondola-0.11.7 → gondola-0.12.0}/src/tof/rb_paddle_id.rs +0 -0
  94. {gondola-0.11.7 → gondola-0.12.0}/src/tof/settings.rs +0 -0
  95. {gondola-0.11.7 → gondola-0.12.0}/src/tof/signal_handler.rs +0 -0
  96. {gondola-0.11.7 → gondola-0.12.0}/src/tof/thread_control.rs +0 -0
  97. {gondola-0.11.7 → gondola-0.12.0}/src/tof/tof_response.rs +0 -0
  98. {gondola-0.11.7 → gondola-0.12.0}/src/tof.rs +0 -0
  99. {gondola-0.11.7 → gondola-0.12.0}/src/tracker/strips.rs +0 -0
  100. {gondola-0.11.7 → gondola-0.12.0}/src/tracker.rs +0 -0
  101. {gondola-0.11.7 → gondola-0.12.0}/src/version.rs +0 -0
  102. {gondola-0.11.7 → gondola-0.12.0}/tests/test.rs +0 -0
@@ -1352,7 +1352,7 @@ checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
1352
1352
 
1353
1353
  [[package]]
1354
1354
  name = "gondola-core"
1355
- version = "0.11.7"
1355
+ version = "0.12.0"
1356
1356
  dependencies = [
1357
1357
  "cfg-if 1.0.0",
1358
1358
  "chrono",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "gondola-core"
3
- version = "0.11.7"
3
+ version = "0.12.0"
4
4
  edition = "2024"
5
5
  readme = "README.md"
6
6
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gondola
3
- Version: 0.11.7
3
+ Version: 0.12.0
4
4
  Requires-Dist: tqdm>=4.0
5
5
  Requires-Dist: numpy>=2.3
6
6
  Requires-Dist: matplotlib>=3.10
@@ -0,0 +1,4 @@
1
+ #! /bin/sh
2
+
3
+ maturin build --release
4
+ scp /srv/gaps/gaps-online-software/gondola-core/rust/gondola-core/target/wheels/gondola-0.11.7-cp311-abi3-manylinux_2_39_x86_64.whl bluejay:gaps-online-software/gander/
@@ -81,7 +81,7 @@ def plot_hg_lg_hits(h_nhits : dashi.histogram.hist1d,
81
81
 
82
82
  #h_nrblnk.line(color='tab:red', label='RB LINK ID')
83
83
 
84
- ###############################################
84
+ #--------------------------------------------------------
85
85
 
86
86
  def tof_projection_xy(paddle_occupancy = {},
87
87
  event = None,
@@ -124,9 +124,10 @@ def tof_projection_xy(paddle_occupancy = {},
124
124
  else:
125
125
  fig, axs = plt.subplots(1, 3, figsize=(18, 5), gridspec_kw={'width_ratios': [1, 1, 1]})
126
126
 
127
- umb_paddles = db.get_umbrella_paddles()
128
- cbe_top_paddles = db.Paddle.objects.filter(panel_id=1)
129
- cbe_bot_paddles = db.Paddle.objects.filter(panel_id=2)
127
+ all_paddles = _gc.db.TofPaddle.all()
128
+ umb_paddles = [k for k in all_paddles if k.paddle_id > 60 and k.paddle_id < 109]
129
+ cbe_top_paddles = [k for k in all_paddles if k.panel_id == 1]
130
+ cbe_bot_paddles = [k for k in all_paddles if k.panel_id == 2]
130
131
  xmin, xmax = -100,100
131
132
  ymin, ymax = -100,100
132
133
  zmin, zmax = -25, 120
@@ -298,6 +299,496 @@ def tof_projection_xy(paddle_occupancy = {},
298
299
 
299
300
  #--------------------------------------------------------
300
301
 
302
+ def unroll_cbe_sides(paddle_occupancy = {},
303
+ event = None,
304
+ cmap = matplotlib.colormaps['hot'],
305
+ paddle_style = {'edgecolor' : 'w', 'lw' : 0.4},
306
+ show_cbar = True,
307
+ indicate_empty = 'gray'
308
+ ):
309
+ """
310
+ Project the sides of the cube on xz and yz as well
311
+ as add the 'edge' paddles.
312
+
313
+ While this plot can show the occupancy of TOF paddles,
314
+ it can also be 'hijacked' to just highlight certain
315
+ paddles.
316
+
317
+ # Keyword Arguments:
318
+ paddle_occupancy : The number of events per paddle
319
+ event : Plot a tof event
320
+ cmap : Colormap - can be lambda function
321
+ to return color value based on
322
+ 'occupancy' numbker
323
+ show_cbar : Show the colorbar on the figure
324
+ indicate_empty : In case we are using this for paddle occupancy,
325
+ indicate empty paddles with the given color instead
326
+ using a value from the color map. If this behavior is
327
+ not desired, set this to an empty string.
328
+ """
329
+ fig, axs = plt.subplots(1, 4, sharey=True,figsize=(22, 5), gridspec_kw={'width_ratios': [1, 1, 1, 1]})
330
+ all_paddles = _gc.db.TofPaddle.all()
331
+ # normal +X
332
+ cbe_front = [ k for k in all_paddles if k.panel_id==3]
333
+ # edge normal +X+Y
334
+ ep_1 = [ k for k in all_paddles if k.paddle_id==57]
335
+ # normal +Y
336
+ cbe_sb = [ k for k in all_paddles if k.panel_id==4]
337
+ # endge normal -X+Y
338
+ ep_2 = [ k for k in all_paddles if k.paddle_id==58]
339
+ # normal -X
340
+ cbe_back = [ k for k in all_paddles if k.panel_id==5]
341
+ # edge normal -X-Y
342
+ ep_3 = [ k for k in all_paddles if k.paddle_id==59]
343
+ # normal -Y
344
+ cbe_bb = [ k for k in all_paddles if k.panel_id==6]
345
+ # edge normal +X-Y
346
+ ep_4 = [ k for k in all_paddles if k.paddle_id==60]
347
+
348
+ xmin, xmax = -110,110
349
+ ymin, ymax = -110,110
350
+ zmin, zmax = -25, 120
351
+ title = 'Relative occupancy, xy projection'
352
+
353
+ if event is not None:
354
+ # coordinates are in mm
355
+ hit_pids = [h.paddle_id for h in event.hits]
356
+ xs = 0.1*np.array([h.x for h in event.hits])
357
+ ys = 0.1*np.array([h.y for h in event.hits])
358
+ zs = 0.1*np.array([h.z for h in event.hits])
359
+ ts = np.array([h.t0 for h in event.hits])
360
+ en = np.array([h.edep for h in event.hits])
361
+ cm_norm_pts = plt.Normalize(vmin=min(ts), vmax=max(ts))
362
+
363
+ ep = ep_1[0]
364
+ cbe_front.append(ep_1[0])
365
+ for pdl in cbe_front:
366
+ if paddle_occupancy:
367
+ color = cmap(paddle_occupancy[pdl.paddle_id])
368
+ if not paddle_occupancy[pdl.paddle_id] and indicate_empty:
369
+ color = indicate_empty
370
+ axs[0].add_patch(pdl.draw_yz(fill=True, edgecolor=color, facecolor=color))
371
+ else:
372
+ if event is not None:
373
+ axs[0].add_patch(pdl.draw_yz(fill=False, facecolor='tab:blue', **paddle_style))
374
+ else:
375
+ axs[0].add_patch(pdl.draw_yz(fill=True, edgecolor='k', facecolor='w'))
376
+
377
+
378
+ ##for pdl in cbe_front:
379
+ ## if paddle_occupancy:
380
+ ## color = cmap(paddle_occupancy[pdl.paddle_id])
381
+ ## axs[0].add_patch(pdl.draw_yz(fill=True, edgecolor=color, facecolor=color))
382
+ ## else:
383
+ ## if event is not None:
384
+ ## axs[0].add_patch(pdl.draw_yz(fill=False, facecolor='tab:blue', **paddle_style))
385
+ ## else:
386
+ ## axs[0].add_patch(pdl.draw_yz(fill=True, edgecolor='k', facecolor='w'))
387
+
388
+ if event is not None:
389
+ #print (hit_pids)
390
+ cbe_front_pids = [k.paddle_id for k in cbe_front]
391
+ for h in event.hits:
392
+ #for j, pdl_hit in enumerate(hit_pids):
393
+ if h.paddle_id in cbe_front_pids:
394
+ axs[0].scatter([0.1*h.y], [0.1*h.z], alpha = 0.8 , marker='o', s=100*h.edep,
395
+ lw=1.5, edgecolor='k', color=cmap(cm_norm_pts(h.t0)))
396
+ axs[0].set_xlabel('y [cm]', loc='right')
397
+ axs[0].set_ylabel('z [cm]', loc='top')#, rotation=90)
398
+ axs[0].set_aspect('equal')
399
+ axs[0].set_xlim(-80, 90)
400
+ axs[0].set_ylim(-10, 120)
401
+ axs[0].set_title('CBE +X', loc='right')
402
+
403
+ # +Y side
404
+ ep = ep_2[0]
405
+ cbe_sb.append(ep_2[0])
406
+ #if paddle_occupancy:
407
+ # color = cmap(paddle_occupancy[ep.paddle_id])
408
+ # if not paddle_occupancy[ep.paddle_id] and indicate_empty:
409
+ # color = indicate_empty
410
+ # axs[1].add_patch(ep.draw_xz(fill=True, edgecolor=color, facecolor=color))
411
+ #else:
412
+ # if event is not None:
413
+ # axs[1].add_patch(ep.draw_xz(fill=False, facecolor='tab:blue', **paddle_style))
414
+ # else:
415
+ # axs[1].add_patch(ep.draw_xz(fill=True, edgecolor='k', facecolor='w'))
416
+
417
+ for pdl in cbe_sb:
418
+ if paddle_occupancy:
419
+ color = cmap(paddle_occupancy[pdl.paddle_id])
420
+ if not paddle_occupancy[pdl.paddle_id] and indicate_empty:
421
+ color = indicate_empty
422
+ axs[1].add_patch(pdl.draw_xz(fill=True, edgecolor=color, facecolor=color))
423
+ else:
424
+ if event is not None:
425
+ axs[1].add_patch(pdl.draw_xz(fill=False, facecolor='tab:blue', **paddle_style))
426
+ else:
427
+ axs[1].add_patch(pdl.draw_xz(fill=True, edgecolor='k', facecolor='w'))
428
+
429
+ if event is not None:
430
+ #print (hit_pids)
431
+ for j, pdl_hit in enumerate(hit_pids):
432
+ if pdl_hit in [umbp.paddle_id for umbp in cbe_sb]:
433
+ axs[1].scatter([xs[j]], [ys[j]], alpha = 0.8 , marker='o', s=100*en[j],
434
+ lw=1.5, edgecolor='k', color=cmap(cm_norm_pts(ts[j])))
435
+ axs[1].set_xlabel('x [cm]', loc='right')
436
+ #axs[1].set_ylabel('z [cm]', loc='top')#, rotation=90)
437
+ axs[1].set_aspect('equal')
438
+ axs[1].set_xlim(-90, 80)
439
+ axs[1].set_ylim(-10, 120)
440
+ axs[1].set_title('CBE +Y', loc='right')
441
+ axs[1].invert_xaxis()
442
+
443
+ ep = ep_3[0]
444
+ cbe_back.append(ep_3[0])
445
+ #if paddle_occupancy:
446
+ # color = cmap(paddle_occupancy[ep.paddle_id])
447
+ # if not paddle_occupancy[ep.paddle_id] and indicate_empty:
448
+ # color = indicate_empty
449
+ # axs[2].add_patch(ep.draw_yz(fill=True, edgecolor=color, facecolor=color))
450
+ #else:
451
+ # if event is not None:
452
+ # axs[2].add_patch(ep.draw_yz(fill=False, facecolor='tab:blue', **paddle_style))
453
+ # else:
454
+ # axs[2].add_patch(ep.draw_yz(fill=True, edgecolor='k', facecolor='w'))
455
+ for pdl in cbe_back:
456
+ if paddle_occupancy:
457
+ color = cmap(paddle_occupancy[pdl.paddle_id])
458
+ if not paddle_occupancy[pdl.paddle_id] and indicate_empty:
459
+ color = indicate_empty
460
+ axs[2].add_patch(pdl.draw_yz(fill=True, edgecolor=color, facecolor=color))
461
+ else:
462
+ if event is not None:
463
+ axs[2].add_patch(pdl.draw_yz(fill=False, facecolor='tab:blue', **paddle_style))
464
+ else:
465
+ axs[2].add_patch(pdl.draw_yz(fill=True, edgecolor='k', facecolor='w'))
466
+ if event is not None:
467
+ #print (hit_pids)
468
+ for j, pdl_hit in enumerate(hit_pids):
469
+ if pdl_hit in [umbp.paddle_id for umbp in cbe_back]:
470
+ axs[2].scatter([ys[j]], [zs[j]], alpha = 0.8 , marker='o', s=100*en[j],
471
+ lw=1.5, edgecolor='k', color=cmap(cm_norm_pts(ts[j])))
472
+ axs[2].set_xlabel('y [cm]', loc='right')
473
+ #axs[2].set_ylabel('z [cm]', loc='top')#, rotation=90)
474
+ axs[2].set_xlim(-90, 80)
475
+ axs[2].set_ylim(-10, 120)
476
+ axs[2].set_aspect('equal')
477
+ axs[2].invert_xaxis()
478
+ axs[2].set_title('CBE -X', loc='right')
479
+
480
+ # -Y side
481
+ ep = ep_4[0]
482
+ cbe_bb.append(ep_4[0])
483
+ #if paddle_occupancy:
484
+ # color = cmap(paddle_occupancy[ep.paddle_id])
485
+ # if not paddle_occupancy[ep.paddle_id] and indicate_empty:
486
+ # color = indicate_empty
487
+ # axs[3].add_patch(ep.draw_xz(fill=True, edgecolor=color, facecolor=color))
488
+ #else:
489
+ # if event is not None:
490
+ # axs[3].add_patch(ep.draw_xz(fill=False, edgecolor='k', facecolor='tab:blue', alpha=0.3))
491
+ # else:
492
+ # axs[3].add_patch(ep.draw_xz(fill=True, edgecolor='k', facecolor='w'))
493
+ for pdl in cbe_bb:
494
+ if paddle_occupancy:
495
+ color = cmap(paddle_occupancy[pdl.paddle_id])
496
+ if not paddle_occupancy[pdl.paddle_id] and indicate_empty:
497
+ color = indicate_empty
498
+ axs[3].add_patch(pdl.draw_xz(fill=True, edgecolor=color, facecolor=color))
499
+ else:
500
+ if event is not None:
501
+ axs[3].add_patch(pdl.draw_xz(fill=False,facecolor='tab:blue', **paddle_style))
502
+ else:
503
+ axs[3].add_patch(pdl.draw_xz(fill=True, edgecolor='k', facecolor='w'))
504
+ if event is not None:
505
+ #print (hit_pids)
506
+ for j, pdl_hit in enumerate(hit_pids):
507
+ if pdl_hit in [umbp.paddle_id for umbp in cbe_bb]:
508
+ axs[3].scatter([xs[j]], [zs[j]], alpha = 0.8 , marker='o', s=100*en[j],
509
+ lw=1.5, edgecolor='k', color=cmap(cm_norm_pts(ts[j])))
510
+
511
+ axs[3].set_xlabel('x [cm]', loc='right')
512
+ #axs[3].set_ylabel('z [cm]', loc='top')#, rotation=90)
513
+ axs[3].set_aspect('equal')
514
+ axs[3].set_xlim(-80, 90)
515
+ axs[3].set_ylim(-10, 120)
516
+ axs[3].set_title('CBE +Y', loc='right')
517
+ #axs[3].invert_xaxis()
518
+
519
+ axs[0].spines['top'].set_visible(True)
520
+ axs[1].spines['top'].set_visible(True)
521
+ axs[2].spines['top'].set_visible(True)
522
+ axs[3].spines['top'].set_visible(True)
523
+ axs[0].spines['right'].set_visible(True)
524
+ axs[1].spines['right'].set_visible(True)
525
+ axs[2].spines['right'].set_visible(True)
526
+ axs[3].spines['right'].set_visible(True)
527
+
528
+ plt.subplots_adjust(wspace=0)
529
+
530
+ if paddle_occupancy and show_cbar:
531
+ cbar_ax = fig.add_axes([0.9, 0.0, 0.05, 1.0])
532
+ cbar_ax.set_axis_off()
533
+ sm = cm.ScalarMappable(cmap=cmap, norm=matplotlib.colors.Normalize())
534
+ sm.set_array([0, 1])
535
+ ax = plt.sca(cbar_ax)
536
+ plt.colorbar(sm, ax=cbar_ax, label='Relative occupancy')
537
+ fig.suptitle(title, x=0.9)
538
+ return fig, axs
539
+
540
+ #--------------------------------------------------------
541
+
542
+ def unroll_cor(paddle_occupancy = {},
543
+ event = None,
544
+ cmap = matplotlib.colormaps['hot'],
545
+ paddle_style = {'edgecolor' : 'w', 'lw' : 0.4},
546
+ show_cbar = True,
547
+ indicate_empty = 'gray'):
548
+ """
549
+ Project the cortina on xz and yz as well
550
+ as add the 'edge' paddles.
551
+
552
+ While this plot can show the occupancy of TOF paddles,
553
+ it can also be 'hijacked' to just highlight certain
554
+ paddles.
555
+
556
+ # Keyword Arguments:
557
+ paddle_occupancy : The number of events per paddle
558
+ cmap : Colormap - can be lambda function
559
+ to return color value based on
560
+ 'occupancy' numbker
561
+ show_cbar : Show the colorbar on the figure
562
+ indicate_empty : In case we are using this for paddle occupancy,
563
+ indicate empty paddles with the given color instead
564
+ using a value from the color map. If this behavior is
565
+ not desired, set this to an empty string.
566
+ """
567
+ fig, axs = plt.subplots(1, 4, sharey=True, figsize=(22, 5), gridspec_kw={'width_ratios': [1, 1, 1, 1]})
568
+ all_paddles = _gc.db.TofPaddle.all()
569
+ # normal +X
570
+ cor_front = [k for k in all_paddles if k.panel_id==14]
571
+ # edge normal +X+Y
572
+ ep_1 = [k for k in all_paddles if k.panel_id==18]
573
+ # normal +Y
574
+ cor_sb = [k for k in all_paddles if k.panel_id==15]
575
+ # endge normal -X+Y
576
+ ep_2 = [k for k in all_paddles if k.panel_id==19]
577
+ # normal -X
578
+ cor_back = [k for k in all_paddles if k.panel_id==16]
579
+ # edge normal -X-Y
580
+ ep_3 = [k for k in all_paddles if k.panel_id==20]
581
+ # normal -Y
582
+ cor_bb = [k for k in all_paddles if k.panel_id==17]
583
+ # edge normal +X-Y
584
+ ep_4 = [k for k in all_paddles if k.panel_id==21]
585
+
586
+ xmin, xmax = -100,130
587
+ ymin, ymax = -25,175 # these are the z-coordinates
588
+ title = 'Relative occupancy, xy projection'
589
+
590
+ if event is not None:
591
+ # coordinates are in mm
592
+ event_hits = sorted(event.hits, key=lambda x : x.t0)
593
+ hit_pids = [h.paddle_id for h in event_hits]
594
+ xs = 0.1*np.array([h.x for h in event_hits])
595
+ ys = 0.1*np.array([h.y for h in event_hits])
596
+ zs = 0.1*np.array([h.z for h in event_hits])
597
+ ts = np.array([h.t0 for h in event_hits])
598
+ en = np.array([h.edep for h in event_hits])
599
+ cm_norm_pts = plt.Normalize(vmin=min(ts), vmax=max(ts))
600
+
601
+ for ep in ep_1:
602
+ if paddle_occupancy:
603
+ color = cmap(paddle_occupancy[ep.paddle_id])
604
+ if not paddle_occupancy[ep.paddle_id] and indicate_empty:
605
+ color = indicate_empty
606
+ axs[0].add_patch(ep.draw_yz(fill=True, edgecolor=color, facecolor=color))
607
+ else:
608
+ if event is not None:
609
+ axs[0].add_patch(ep.draw_yz(fill=False, facecolor='tab:blue', **paddle_style))
610
+ else:
611
+ axs[0].add_patch(ep.draw_yz(fill=True, edgecolor='k', facecolor='w'))
612
+ if event is not None:
613
+ for j, pdl_hit in enumerate(hit_pids):
614
+ if pdl_hit in [pdl_.paddle_id for pdl_ in ep_1]:
615
+ axs[0].scatter([ys[j]], [zs[j]], alpha = 0.8 , marker='o', s=100*en[j],
616
+ lw=1.5, edgecolor='k', color=cmap(cm_norm_pts(ts[j])))
617
+
618
+ for pdl in cor_front:
619
+ if paddle_occupancy:
620
+ color = cmap(paddle_occupancy[pdl.paddle_id])
621
+ if not paddle_occupancy[pdl.paddle_id] and indicate_empty:
622
+ color = indicate_empty
623
+ axs[0].add_patch(pdl.draw_yz(fill=True, edgecolor=color, facecolor=color))
624
+ else:
625
+ if event is not None:
626
+ axs[0].add_patch(pdl.draw_yz(fill=False, facecolor='tab:blue', **paddle_style))
627
+ else:
628
+ axs[0].add_patch(pdl.draw_yz(fill=True, edgecolor='k', facecolor='w'))
629
+
630
+ if event is not None:
631
+ for j, pdl_hit in enumerate(hit_pids):
632
+ if pdl_hit in [pdl_.paddle_id for pdl_ in cor_front]:
633
+ axs[0].scatter([ys[j]], [zs[j]], alpha = 0.8 , marker='o', s=100*en[j],
634
+ lw=1.5, edgecolor='k', color=cmap(cm_norm_pts(ts[j])))
635
+
636
+ axs[0].set_xlabel('y [cm]', loc='right')
637
+ axs[0].set_ylabel('z [cm]', loc='top')#, rotation=90)
638
+ #axs[0].set_aspect('equal')
639
+ axs[0].set_xlim(xmin, xmax)
640
+ axs[0].set_ylim(ymin, ymax)
641
+ axs[0].set_title('COR +X', loc='right')
642
+
643
+ # +Y side
644
+ for ep in ep_2:
645
+ if paddle_occupancy:
646
+ color = cmap(paddle_occupancy[ep.paddle_id])
647
+ if not paddle_occupancy[ep.paddle_id] and indicate_empty:
648
+ color = indicate_empty
649
+ axs[1].add_patch(ep.draw_xz(fill=True, edgecolor=color, facecolor=color))
650
+ else:
651
+ if event is not None:
652
+ axs[1].add_patch(ep.draw_xz(fill=False, facecolor='tab:blue', **paddle_style))
653
+ else:
654
+ axs[1].add_patch(ep.draw_xz(fill=True, edgecolor='k', facecolor='w'))
655
+ if event is not None:
656
+ for j, pdl_hit in enumerate(hit_pids):
657
+ if pdl_hit in [pdl_.paddle_id for pdl_ in ep_2]:
658
+ axs[1].scatter([xs[j]], [zs[j]], alpha = 0.8 , marker='o', s=100*en[j],
659
+ lw=1.5, edgecolor='k', color=cmap(cm_norm_pts(ts[j])))
660
+
661
+ for pdl in cor_sb:
662
+ if paddle_occupancy:
663
+ color = cmap(paddle_occupancy[pdl.paddle_id])
664
+ if not paddle_occupancy[pdl.paddle_id] and indicate_empty:
665
+ color = indicate_empty
666
+ axs[1].add_patch(pdl.draw_xz(fill=True, edgecolor=color, facecolor=color))
667
+ else:
668
+ if event is not None:
669
+ axs[1].add_patch(pdl.draw_xz(fill=False, facecolor='tab:blue', **paddle_style))
670
+ else:
671
+ axs[1].add_patch(pdl.draw_xz(fill=True, edgecolor='k', facecolor='w'))
672
+ if event is not None:
673
+ for j, pdl_hit in enumerate(hit_pids):
674
+ if pdl_hit in [pdl_.paddle_id for pdl_ in cor_sb]:
675
+ axs[1].scatter([zs[j]], [zs[j]], alpha = 0.8 , marker='o', s=100*en[j],
676
+ lw=1.5, edgecolor='k', color=cmap(cm_norm_pts(ts[j])))
677
+ axs[1].set_xlabel('x [cm]', loc='right')
678
+ #axs[1].set_ylabel('z [cm]', loc='top')#, rotation=90)
679
+ #axs[1].set_aspect('equal')
680
+ axs[1].set_xlim(-1*xmax, -1*xmin)
681
+ axs[1].set_ylim(ymin, ymax)
682
+ axs[1].set_title('COR +Y', loc='right')
683
+ axs[1].invert_xaxis()
684
+
685
+ for ep in ep_3:
686
+ if paddle_occupancy:
687
+ color = cmap(paddle_occupancy[ep.paddle_id])
688
+ if not paddle_occupancy[ep.paddle_id] and indicate_empty:
689
+ color = indicate_empty
690
+ axs[2].add_patch(ep.draw_yz(fill=True, edgecolor=color, facecolor=color))
691
+ else:
692
+ if event is not None:
693
+ axs[2].add_patch(ep.draw_yz(fill=False, facecolor='tab:blue', **paddle_style))
694
+ else:
695
+ axs[2].add_patch(ep.draw_yz(fill=True, edgecolor='k', facecolor='w'))
696
+ if event is not None:
697
+ for j, pdl_hit in enumerate(hit_pids):
698
+ if pdl_hit in [pdl_.paddle_id for pdl_ in ep_3]:
699
+ axs[2].scatter([ys[j]], [zs[j]], alpha = 0.8 , marker='o', s=100*en[j],
700
+ lw=1.5, edgecolor='k', color=cmap(cm_norm_pts(ts[j])))
701
+
702
+ for pdl in cor_back:
703
+ if paddle_occupancy:
704
+ color = cmap(paddle_occupancy[pdl.paddle_id])
705
+ if not paddle_occupancy[pdl.paddle_id] and indicate_empty:
706
+ color = indicate_empty
707
+ axs[2].add_patch(pdl.draw_yz(fill=True, edgecolor=color, facecolor=color))
708
+ else:
709
+ if event is not None:
710
+ axs[2].add_patch(pdl.draw_yz(fill=False, facecolor='tab:blue', **paddle_style))
711
+ else:
712
+ axs[2].add_patch(pdl.draw_yz(fill=True, edgecolor='k', facecolor='w'))
713
+
714
+ if event is not None:
715
+ for j, pdl_hit in enumerate(hit_pids):
716
+ if pdl_hit in [pdl_.paddle_id for pdl_ in cor_back]:
717
+ axs[2].scatter([ys[j]], [zs[j]], alpha = 0.8 , marker='o', s=100*en[j],
718
+ lw=1.5, edgecolor='k', color=cmap(cm_norm_pts(ts[j])))
719
+ axs[2].set_xlabel('y [cm]', loc='right')
720
+ #axs[2].set_ylabel('z [cm]', loc='top')#, rotation=90)
721
+ axs[2].set_xlim(-1*xmax, -1*xmin)
722
+ axs[2].set_ylim(ymin, ymax)
723
+ #axs[2].set_aspect('equal')
724
+ axs[2].invert_xaxis()
725
+ axs[2].set_title('COR -X', loc='right')
726
+
727
+ # -Y side
728
+ for ep in ep_4:
729
+ if paddle_occupancy:
730
+ color = cmap(paddle_occupancy[ep.paddle_id])
731
+ if not paddle_occupancy[ep.paddle_id] and indicate_empty:
732
+ color = indicate_empty
733
+ axs[3].add_patch(ep.draw_xz(fill=True, edgecolor=color, facecolor=color))
734
+ else:
735
+ if event is not None:
736
+ axs[3].add_patch(ep.draw_xz(fill=False, facecolor='tab:blue', **paddle_style))
737
+ else:
738
+ axs[3].add_patch(ep.draw_xz(fill=True, edgecolor='k', facecolor='w'))
739
+ if event is not None:
740
+ for j, pdl_hit in enumerate(hit_pids):
741
+ if pdl_hit in [pdl_.paddle_id for pdl_ in ep_4]:
742
+ axs[3].scatter([xs[j]], [zs[j]], alpha = 0.8 , marker='o', s=100*en[j],
743
+ lw=1.5, edgecolor='k', color=cmap(cm_norm_pts(ts[j])))
744
+
745
+ for pdl in cor_bb:
746
+ if paddle_occupancy:
747
+ color = cmap(paddle_occupancy[pdl.paddle_id])
748
+ if not paddle_occupancy[pdl.paddle_id] and indicate_empty:
749
+ color = indicate_empty
750
+ axs[3].add_patch(pdl.draw_xz(fill=True, edgecolor=color, facecolor=color))
751
+ else:
752
+ if event is not None:
753
+ axs[3].add_patch(pdl.draw_xz(fill=False, facecolor='tab:blue', **paddle_style))
754
+ else:
755
+ axs[3].add_patch(pdl.draw_xz(fill=True, edgecolor='k', facecolor='w'))
756
+
757
+ if event is not None:
758
+ for j, pdl_hit in enumerate(hit_pids):
759
+ if pdl_hit in [pdl_.paddle_id for pdl_ in cor_bb]:
760
+ axs[3].scatter([xs[j]], [zs[j]], alpha = 0.8 , marker='o', s=100*en[j],
761
+ lw=1.5, edgecolor='k', color=cmap(cm_norm_pts(ts[j])))
762
+
763
+ axs[3].set_xlabel('x [cm]', loc='right')
764
+ #axs[3].set_ylabel('z [cm]', loc='top')#, rotation=90)
765
+ #axs[3].set_aspect('equal')
766
+ axs[3].set_xlim(xmin, xmax)
767
+ axs[3].set_ylim(ymin, ymax)
768
+ axs[3].set_title('COR +Y', loc='right')
769
+ #axs[3].invert_xaxis()
770
+
771
+ axs[0].spines['top'].set_visible(True)
772
+ axs[1].spines['top'].set_visible(True)
773
+ axs[2].spines['top'].set_visible(True)
774
+ axs[3].spines['top'].set_visible(True)
775
+ axs[0].spines['right'].set_visible(True)
776
+ axs[1].spines['right'].set_visible(True)
777
+ axs[2].spines['right'].set_visible(True)
778
+ axs[3].spines['right'].set_visible(True)
779
+
780
+ plt.subplots_adjust(wspace=0)
781
+
782
+ if paddle_occupancy and show_cbar:
783
+ cbar_ax = fig.add_axes([0.9, 0.0, 0.05, 1.0])
784
+ cbar_ax.set_axis_off()
785
+ sm = cm.ScalarMappable(cmap=cmap, norm=matplotlib.colors.Normalize())
786
+ sm.set_array([0, 1])
787
+ ax = plt.sca(cbar_ax)
788
+ plt.colorbar(sm, ax=cbar_ax, label='Relative occupancy')
789
+ fig.suptitle(title, x=0.9)
790
+ return fig, axs
791
+
301
792
  def tof_2dproj(event = None,
302
793
  cmap = matplotlib.colormaps['seismic'],
303
794
  paddle_style = {'edgecolor' : 'w', 'lw' : 0.4},
@@ -9,7 +9,7 @@ use crate::prelude::*;
9
9
  /// to the beginning by a given offset.
10
10
  ///
11
11
  /// This is similar to
12
- /// https://numpy.org/doc/2.2/reference/generated/numpy.roll.html
12
+ /// <https://numpy.org/doc/2.2/reference/generated/numpy.roll.html>
13
13
  ///
14
14
  /// # Arguments:
15
15
  /// * `vec` : The vector to be rolled over. It will
@@ -1782,6 +1782,7 @@ impl RBCalibrations {
1782
1782
  }
1783
1783
  }
1784
1784
 
1785
+ #[cfg(feature = "pybindings")]
1785
1786
  pythonize_packable_no_new!(RBCalibrations);
1786
1787
 
1787
1788
  #[cfg(feature = "random")]
@@ -3,7 +3,6 @@
3
3
 
4
4
  use crate::prelude::*;
5
5
 
6
-
7
6
  /// Waveform container for Tof waveforms
8
7
  /// This holds the waveforms for both
9
8
  /// paddle ends. Fields are available to
@@ -14,13 +13,16 @@ use crate::prelude::*;
14
13
  pub struct RBWaveform {
15
14
  pub event_id : u32,
16
15
  pub rb_id : u8,
17
- /// FIXME - this is form 0-8, but should it be from 1-9?
16
+ ///// FIXME - this is form 0-8, but should it be from 1-9?
18
17
  pub rb_channel_a : u8,
19
18
  pub rb_channel_b : u8,
20
19
  /// DRS4 stop cell
21
20
  pub stop_cell : u16,
22
21
  pub adc_a : Vec<u16>,
23
22
  pub adc_b : Vec<u16>,
23
+ // FIXME - to be compatible with Antarctica data from
24
+ // 2024/25, we do not serialize the paddle id in this version
25
+ // HOWEVER, let's change that in v0.12
24
26
  pub paddle_id : u8,
25
27
  pub voltages_a : Vec<f32>,
26
28
  pub nanoseconds_a : Vec<f32>,
@@ -238,6 +240,9 @@ impl Serialization for RBWaveform {
238
240
  let data_a = &stream[*pos..*pos+2*NWORDS];
239
241
  wf.adc_a = u8_to_u16(data_a);
240
242
  *pos += 2*NWORDS;
243
+ if stream.len() < *pos+2*NWORDS {
244
+ return Err(SerializationError::StreamTooShort);
245
+ }
241
246
  let data_b = &stream[*pos..*pos+2*NWORDS];
242
247
  wf.adc_b = u8_to_u16(data_b);
243
248
  *pos += 2*NWORDS;
@@ -449,6 +454,10 @@ impl RBWaveform {
449
454
  #[cfg(feature="pybindings")]
450
455
  pythonize_packable!(RBWaveform);
451
456
 
457
+ // needs to fix something up
458
+ //#[cfg(feature="pybindings")]
459
+ //pythonize_telemetry!(RBWaveform);
460
+
452
461
  //---------------------------------------------------
453
462
 
454
463
  #[cfg(feature = "random")]
@@ -319,7 +319,7 @@ impl TofEvent {
319
319
  h.event_t0 = t0 + t_shift;
320
320
  }
321
321
  // start the first hit at 0
322
- self.hits.sort_by(|a,b| (a.event_t0).partial_cmp(&b.event_t0).unwrap());
322
+ self.hits.sort_by(|a,b| (a.event_t0).partial_cmp(&b.event_t0).unwrap_or(Ordering::Greater));
323
323
  let t0_first_hit = self.hits[0].event_t0;
324
324
  for h in self.hits.iter_mut() {
325
325
  h.event_t0 -= t0_first_hit
@@ -428,8 +428,6 @@ impl TofEvent {
428
428
  /// Vec<(hit)> where hit is (DSI, J, CH)
429
429
  pub fn get_trigger_hits(&self) -> Vec<(u8, u8, (u8, u8), LTBThreshold)> {
430
430
  let mut hits = Vec::<(u8,u8,(u8,u8),LTBThreshold)>::with_capacity(5);
431
- let physical_channels = [(1u8, 2u8), (3u8,4u8), (5u8, 6u8), (7u8, 8u8),
432
- (9u8, 10u8), (11u8,12u8), (13u8, 14u8), (15u8, 16u8)];
433
431
  //let n_masks_needed = self.dsi_j_mask.count_ones() / 2 + self.dsi_j_mask.count_ones() % 2;
434
432
  let n_masks_needed = self.dsi_j_mask.count_ones();
435
433
  if self.channel_mask.len() < n_masks_needed as usize {
@@ -469,7 +467,7 @@ impl TofEvent {
469
467
  let channels = self.channel_mask[n_mask];
470
468
  for (i,ch) in LTB_CHANNELS.iter().enumerate() {
471
469
  //let chn = *ch as u8 + 1;
472
- let ph_chn = physical_channels[i];
470
+ let ph_chn = PHYSICAL_CHANNELS[i];
473
471
  //let chn = i as u8 + 1;
474
472
  //println!("i,ch {}, {}", i, ch);
475
473
  let thresh_bits = ((channels & ch) >> (i*2)) as u8;
@@ -770,8 +770,8 @@ impl FromRandom for TofHit {
770
770
  fn from_random() -> TofHit {
771
771
  let mut pp = TofHit::new();
772
772
  let mut rng = rand::rng();
773
-
774
- pp.paddle_id = rng.random::<u8> ();
773
+
774
+ pp.paddle_id = rng.random_range(0..161);
775
775
  pp.time_a = f16::from_f32(rng.random::<f32>());
776
776
  pp.time_b = f16::from_f32(rng.random::<f32>());
777
777
  pp.peak_a = f16::from_f32(rng.random::<f32>());
@@ -74,6 +74,11 @@ pub const LTB_CHANNELS : [u16;8] = [
74
74
  LTB_CH7
75
75
  ];
76
76
 
77
+ /// An array of the channel numbers as they come in pairs on the LTB
78
+ pub const PHYSICAL_CHANNELS : [(u8, u8); 8] = [(1u8, 2u8), (3u8,4u8), (5u8, 6u8), (7u8, 8u8),
79
+ (9u8, 10u8), (11u8,12u8), (13u8, 14u8), (15u8, 16u8)];
80
+
81
+
77
82
  /// Calculate an unique identifier for
78
83
  /// tracker strips from the position in
79
84
  /// the tracker stack
@@ -134,7 +134,7 @@ pub fn parse_string<T: AsRef<[u8]>>(stream : &T, pos : &mut usize) -> String {
134
134
  /// representation of u32 (neither le or be, but
135
135
  /// shuffled)
136
136
  ///
137
- /// <div class="warning>
137
+ /// <div class="warning">
138
138
  /// This assumes an underlying representation of
139
139
  /// an atomic unit of 16bit instead of 8.
140
140
  /// This is a non-convetional byte respresentation