Skip to content
apausaPublic
forked from iLCSoft/CED

About

Small C++ Event Display

Resources

Stars

0 stars

Watchers

0 watching

Forks

 
 

Latest commit

 

History

449 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Small C++ Event Display (SCED)

SCED is a server client application for OpenGL drawing

I would like to remove header files from include& can you move them to where they b

License

CED is distributed under the GPLv3 License

License

Build instructions in MacOS with Homebrew

# Install libraries (fontconfig and OpenGL are already preinstalled)
brew install sdl3 sdl3_ttf glm cmake

# Configure build
cmake -S . -B build -DCMAKE_PREFIX_PATH="/opt/homebrew/opt/sdl3;/opt/homebrew/opt/sdl3_ttf;/opt/homebrew/opt/glm;/opt/homebrew/opt/fontconfig"

# Compile project
cmake --build build -j4

# Run server
./build/sced-server

Build instructions in Alma 9

Install and build dependencies

# glm-devel and libdecor-devel are in CRB
sudo dnf config-manager --set-enabled crb

sudo dnf install gcc-c++ cmake git glm-devel fontconfig-devel libglvnd-devel \
    mesa-libEGL-devel mesa-libgbm-devel libdrm-devel dbus-devel \
    wayland-devel wayland-protocols-devel libxkbcommon-devel libdecor-devel

mkdir -p ~/src && cd ~/src
PREFIX=$HOME/sdl3

# SDL3
git clone --depth 1 --branch release-3.4.8 https://github.com/libsdl-org/SDL.git
cmake -S SDL -B SDL/build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PREFIX -DSDL_X11_XSCRNSAVER=OFF
cmake --build SDL/build -j$(nproc)
cmake --install SDL/build

# SDL3_ttf
git clone --recursive --depth 1 --branch release-3.2.2 https://github.com/libsdl-org/SDL_ttf.git
cmake -S SDL_ttf -B SDL_ttf/build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PREFIX -DCMAKE_PREFIX_PATH=$PREFIX
cmake --build SDL_ttf/build -j$(nproc)
cmake --install SDL_ttf/build

Install and build SCED

# Configure build
cmake -S . -B build -DCMAKE_PREFIX_PATH="$HOME/sdl3"

# Compile project
cmake --build build -j$(nproc)

# Run project
./build/sced-server

Kill server

pkill -f sced-server

sced-server command line options

sced-server -h  # show help
sced-server     # run event display server

Controls for CED display server (sced-server window):

The window has to be active and the mouse placed inside it.

Keyboard shortcuts:

	ESC .......... quit
	CTRL+s ....... save screenshot
	keys [0-9] ... toggle visibility layers
	key 'r' ...... redispaly in some initial projection
	key 'f' ...... front projection
	key 's' ...... side projection
	key 'c' ...... move center of rotation to the nearest hit within current mouse position
	key 'v' ...... fish-eye view
	key 'b' ...... toggle background color
	key 'h' ...... display help menu

Mouse interaction:

	L button + drag:    rotate
	R button + drag:    pop-up menu
	M button + drag:    shift
	M wheel  + up  :    zoom-in
	M wheel  + down:    zoom-out

Using the CED client library with Marlin:

Somewhere at the beginning of file ******Processor.cc

	#include <ced_cli.h>

	//   Visibility layers types: should be included as:
	#define PHOTON_LAYER (0<<CED_LAYER_SHIFT)
	#define PHOTON_LAYER (1<<CED_LAYER_SHIFT)
	#define NHADR_LAYER  (2<<CED_LAYER_SHIFT)
	#define CHADR_LAYER  (3<<CED_LAYER_SHIFT)
	#define TPC_LAYER    (4<<CED_LAYER_SHIFT)
	#define ECAL_LAYER   (5<<CED_LAYER_SHIFT)
	#define HCAL_LAYER   (6<<CED_LAYER_SHIFT)
	     ...........................
	#define SOME_LAYER   (19<<CED_LAYER_SHIFT)

Once per task in first init:

  void *********Processor::init() {
  //    Initialize event display
    ced_client_init("localhost",7286);
    ced_register_elements();

In the first called Processor::processEvent( LCEvent * evt ) initialize the geometry:

	//-----------------------------------------------------------------------
	  ced_new_event();  // Reset drawing buffer and START drawing collection
	  //          The Simplest geometry has Z axis as beam axis
	  static CED_GeoCylinder geoCylinders[] = {       // for TESLA Detector Geometry
	    {    50.0,  6,  0.0, 5658.5, -5658.5, 0xff      }, // beam tube
	    {   380.0, 24,  0.0, 2658.5, -2658.5, 0xff      }, // inner TPC
	    {  1840.0,  8, 22.5, 2700.0, -2700.0, 0x7f7f1f  }, // inner ECAL
	    {  2045.7,  8, 22.5, 2700.0, -2700.0, 0x7f7f1f  }, // outer ECAL
	    {  2045.7,  8, 22.5, 101.00,  2820.0, 0x7f7f1f  }, // endcap ECAL
	    {  2045.7,  8, 22.5, 101.00, -3022.0, 0x7f7f1f  }, // endcap ECAL
	    {  3000.0, 16,  0.0, 2658.5, -2658.5, 0xcf00    }, // outer HCAL
	    {  3000.0,  8, 22.5, 702.25,  2826.0, 0xcf00    }, // endcap HCAL
	    {  3000.0,  8, 22.5, 702.25, -4230.5, 0xcf00    }, // endcap HCAL
	// radius,poligon order,angle degree,1/2 length,shift in z, color
	  };

	  /*
	  static CED_GeoCylinder geoCylinders[] = {    // for Prototype
	    {    180.0,  4,  45.0, 110.0, 0.0, 0xff }, // ECAL
	    {    500.0,  4,  45.0, 250.0, 220., 0xff } // HCAL
	  };
	  */

	  ced_geocylinders(sizeof(geoCylinders)/sizeof(CED_GeoCylinder),geoCylinders);
	//------------------------------------------------------------------

One can put here as many cylinders as one want.

In any Processor:

	  void ********Processor::processEvent( LCEvent * evt ) {

	//  hit/point types are predefined as
	//    CED_HIT_POINT=0,
	//    CED_HIT_CROSS=1,
	//    CED_HIT_STAR=2,

	//in loop:   one can call either hit drawing or line drawing with functions:

	// void ced_hit(float x,float y,float z,unsigned type,unsigned size,unsigned color);
	// void ced_line(float x0,float y0,float z0,
	//	      float x1,float y1,float z1,
	//	      unsigned type,unsigned width,unsigned color);

    // same as ced_hit_ID, with a time "t" (in seconds) attached to the hit. The server currently ignores it and draws the hit immediately.
	// void ced_hit_ID_animate(float x,float y,float z, float t, unsigned type, unsigned size, unsigned color, unsigned id);

to define colors is better use gimp - it gives that crasy numbers easily

	// Possible type combinations:

	// real call
	     for (int i=0; i<nn,i++){ // along hit/point collection or so
	       kcol = 0xf2290e;
	//  ECAL_LAYER-- mean hit will be switch on/off by keyboad key number 5 and
	//       will draw as CED_POINT i.e. .
	 	 ced_hit(cc_red[kk][nn].x,cc_red[kk][nn].y,cc_red[kk][nn].z,ECAL_LAYER,3,kcol);

	       kcol = 0x25cb17;
	//  HCAL_LAYER|2 -- mean hit will be switch on/off by keyboad key number 6 and
	//  will draw as CED_HIT_STAR i.e. *
		 ced_hit(cc_blue[kk][nn].x,cc_blue[kk][nn].y,cc_blue[kk][nn].z,HCAL_LAYER|2,3,kcol);

	//or:
	         ced_line(x1,y1,z1,x2,y2,z2, CHADR_LAYER , 1, 0x7af774);
	}

	// after loop
	   ced_send_event();    // Does not clean up screen


	// at the end of event
	  ced_draw_event();    // Make clean up screen before drawing

Using the CED client library with EDM4hep files in python:

One must use key4hep environment, e.g.:

source /cvmfs/sw.hsf.org/key4hep/setup.sh
# or
# source /cvmfs/sw-nightlies.hsf.org/key4hep/setup.sh
import os
import cppyy
from podio import root_io

# User Config
COMPACT_PATH="<path-to-compact-file>"
EDM4HEP_FILE = "<path-to-edm4hep-file>"
TRACKER_HIT_COLS = ["<name-of-tracker-hit-col-1>", "<name-of-tracker-hit-col-2>", "<...>"]
CALO_HIT_COLS = ["<name-of-calo-hit-col-1>", "<name-of-calo-hit-col-2>", "<...>"]

# Load dependencies
for path in os.environ["CMAKE_PREFIX_PATH"].split(":"):
    inlcude_dir = os.path.join(path, "include")
    if os.path.isdir(inlcude_dir):
        cppyy.add_include_path( inlcude_dir )

    if "/marlinutil/" in path:
        cppyy.add_include_path( os.path.join(path, "include", "marlinutil") )

cppyy.include("ced_cli.h")
cppyy.include("DDMarlinCED.h")
from cppyy.gbl import ced_client_init, ced_register_elements
from cppyy.gbl import ced_new_event, ced_send_event, ced_selected_id_noblock
from cppyy.gbl import ced_hit_ID, ced_hit_ID_animate, CED_HIT_POINT
std = cppyy.gbl.std
DDMarlinCED = cppyy.gbl.DDMarlinCED

det_compact_file = os.path.join( os.environ["k4geo_DIR"], COMPACT_PATH )
detector = cppyy.gbl.dd4hep.Detector.getInstance()
detector.fromCompact(det_compact_file)

ced_client_init("localhost", 7286)
ced_register_elements()

reader = root_io.Reader(EDM4HEP_FILE)
for event in reader.get("events"):
    ced_new_event()

    DDMarlinCED.drawDD4hepDetector( detector, False, std.vector[std.string]() )

    layer = 1  # layer under which hits are displayed
    timed_layer = 2
    size = 5  # size of the hits
    color = 0x000000  # hex color of the hits
    # Draw all reconstructed hits in layer #1, and again in layer #2 with their time attached (the server does not animate them)
    for col in TRACKER_HIT_COLS + CALO_HIT_COLS:
        for hit in event.get(col):
            pos = hit.getPosition()
            t = hit.getTime()
            ced_hit_ID(pos.x, pos.y, pos.z, CED_HIT_POINT, layer, size, color, 0)
            ced_hit_ID_animate(pos.x, pos.y, pos.z, t, CED_HIT_POINT, timed_layer, size, color, 0)

    ced_send_event()

    # ced_selected_id_noblock() can be used to return id of the picked object.
    # A more involved example with kbhit instead of pyhton's input() would be needed to use it.
    # picked_id = ced_selected_id_noblock()

    input("Press enter to draw next event")

License and Copyright

Copyright (C) 2005-2026, CED Authors

CED is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License long with this program. If not, see http://www.gnu.org/licenses/.

About

Small C++ Event Display

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages