diff --git a/README.md b/README.md index b7773ee..eb4e5bf 100644 --- a/README.md +++ b/README.md @@ -150,6 +150,9 @@ In any Processor: // float x1,float y1,float z1, // unsigned type,unsigned width,unsigned color); + // hit rendering is delayed by the time "t" (in seconds). Produce animation effect. "Show FPS" must be switched on. + // 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 @@ -178,9 +181,79 @@ to define colors is better use gimp - it gives that crasy numbers easily // 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.: +```bash +source /cvmfs/sw.hsf.org/key4hep/setup.sh +# or +# source /cvmfs/sw-nightlies.hsf.org/key4hep/setup.sh +``` + +```python +import os +import cppyy +from podio import root_io + +# User Config +COMPACT_PATH="" +EDM4HEP_FILE = "" +TRACKER_HIT_COLS = ["", "", "<...>"] +CALO_HIT_COLS = ["", "", "<...>"] + +# 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 + animated_layer = 2 + size = 5 # size of the hits + color = 0x000000 # hex color of the hits + # Draw all reconstructed hits in layer #1 and animate them in layer #2 + 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, animated_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-2017, CED Authors +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. diff --git a/include/ced_cli.h b/include/ced_cli.h index a92164b..69502c1 100644 --- a/include/ced_cli.h +++ b/include/ced_cli.h @@ -129,6 +129,7 @@ typedef enum { typedef struct { CED_Point p; + float time; // allows event animation unsigned type; // point, star, etc unsigned layer; //layer unsigned color; // in ARGB form (so, 0xff0000 is RED) @@ -144,6 +145,8 @@ void ced_hit_ID_old(float x,float y,float z,unsigned type, unsigned size,unsigne void ced_hit_ID(float x,float y,float z,unsigned type,unsigned layer, unsigned size,unsigned color, unsigned lcioID); +void ced_hit_ID_animate(float x,float y,float z,float t, unsigned type,unsigned layer, unsigned size,unsigned color, unsigned lcioID); + /* * Line element */ diff --git a/src/ced.h b/src/ced.h index ccf355c..b2abaf0 100644 --- a/src/ced.h +++ b/src/ced.h @@ -121,6 +121,8 @@ struct CEDsettings{ int autoshot_scale; // If true, generate screencapture in every new event }; +extern int animation_start_time; // in ms +extern int animate_layer; /* //important: // - sum of all layers must be smaler than max_layer! diff --git a/src/client/ced_cli.cc b/src/client/ced_cli.cc index 8c063e1..0e6449a 100644 --- a/src/client/ced_cli.cc +++ b/src/client/ced_cli.cc @@ -34,6 +34,7 @@ void ced_hit_ID(float x,float y,float z,unsigned type,unsigned layer, unsigned s h->p.x=x; h->p.y=y; h->p.z=z; + h->time=0; h->type=type; // if(layer > 255){ //downward compability // h->layer=layer >> CED_LAYER_SHIFT; @@ -45,6 +46,22 @@ void ced_hit_ID(float x,float y,float z,unsigned type,unsigned layer, unsigned s h->lcioID=lcioID; } +void ced_hit_ID_animate(float x,float y,float z,float t, unsigned type,unsigned layer, unsigned size,unsigned color, unsigned lcioID){ + CED_Hit *h=(CED_Hit *)ced_add(HIT_ID); + if(!h) return; + h->p.x=x; + h->p.y=y; + h->p.z=z; + h->time=t; + h->type=type; + h->layer=layer; + h->size=size; + h->color=color; + h->lcioID=lcioID; +} + + + /* * Line element */ diff --git a/src/server/ced_srv.cc b/src/server/ced_srv.cc index abef8a3..7a3ba4c 100644 --- a/src/server/ced_srv.cc +++ b/src/server/ced_srv.cc @@ -1290,11 +1290,28 @@ static void ced_draw_hit(CED_Hit *h){ } //printf("hit on layer: %i\n", h->layer); + + // time is passed to the hit data and is expected to be animated + bool to_animate = h->time > 0.f; + if ( to_animate && animate_layer == -1 ) animation_start_time = glutGet(GLUT_ELAPSED_TIME); + if(!IS_VISIBLE(h->layer)){ + if (to_animate && animate_layer == int(h->layer) ) animate_layer = -1; return; } // printf("Draw hit at : %f %f %f type = %d and ced_visible_layers = %d \n",h->p.x,h->p.y,h->p.z,h->type,ced_visible_layers); + if (to_animate){ + if ( animate_layer == -1 ) animate_layer = h->layer; + else if ( animate_layer != int(h->layer) ){ + setting.layer[animate_layer] = false; + animate_layer = h->layer; + animation_start_time = glutGet(GLUT_ELAPSED_TIME); + } + float elapsed_time = 0.001*( glutGet(GLUT_ELAPSED_TIME) - animation_start_time); // in seconds + if ( elapsed_time < h->time ) return ; + } + ced_color(h->color); diff --git a/src/server/glced.cc b/src/server/glced.cc index 2323452..d5733b8 100644 --- a/src/server/glced.cc +++ b/src/server/glced.cc @@ -96,6 +96,8 @@ int ced_picking(int x,int y,GLfloat *wx,GLfloat *wy,GLfloat *wz); //from ced_srv //*************** global variables ***************************************// +int animation_start_time = 0; +int animate_layer = -1; //for new angles add the new angle to this list and to define in ced_menu.h static int available_cutangles[]={0,30,45,90,100,135,120,150,170,180,190,200,220,240,260,270,280,290,310,330,340}; int last_selected_layer; @@ -560,6 +562,41 @@ std::string formatShortcut(int iLayer, const char key, const char *description, return truncateTo(sstr.str(), max_len); } +void printEventTime(void){ + if( animate_layer < 0 ) return; + + //calculate event time: + float elapsed_time = 0.001*( glutGet(GLUT_ELAPSED_TIME) - animation_start_time); // in seconds, but physicswise should be in ns + char text[42]; + sprintf(text, "Event time: %.3f ns", elapsed_time); + double dark = 1.-(setting.bgcolor[0]+setting.bgcolor[1]+setting.bgcolor[2]) / 3.0; + + //print on screen: + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + GLfloat w=glutGet(GLUT_SCREEN_WIDTH); + GLfloat h=glutGet(GLUT_SCREEN_HEIGHT); + glOrtho(-WORLD_SIZE*w/h,WORLD_SIZE*w/h,-WORLD_SIZE,WORLD_SIZE, -15*WORLD_SIZE,15*WORLD_SIZE); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glColor3f(dark,dark,dark); + drawHelpString(text, -600, -950); + + + glEnd(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); +} + void printShortcuts(void){ @@ -776,6 +813,7 @@ static void display(void){ ced_menu->draw(); popupmenu->draw(); printFPS(); + printEventTime(); if(setting.light==true){ glEnable(GL_LIGHTING); @@ -4524,6 +4562,9 @@ int main(int argc,char *argv[]){ + //future calls give time relative to this. + glutGet(GLUT_ELAPSED_TIME); // time since glutInit() + animation_start_time = glutGet(GLUT_ELAPSED_TIME); // time since first glutGet(GLUT_ELAPSED_TIME) glutMainLoop(); return 0;