hits.cxx
Go to the documentation of this file.
1 #include <gtk/gtk.h>
2 #include <vector>
3 #include <algorithm>
4 #include <stdint.h>
5 #include "event.h"
6 #include "drawing.h"
7 #include "geo.h"
8 #include "status.h"
9 
10 extern std::vector<noeevent> theevents;
11 extern int gevi;
12 extern int pixx, pixy;
13 extern int active_plane, active_cell;
14 
15 static bool by_charge(const hit & a, const hit & b)
16 {
17  return a.adc < b.adc;
18 }
19 
20 __attribute__((unused)) static bool by_time(const hit & a, const hit & b)
21 {
22  return a.tdc < b.tdc;
23 }
24 
25 // Given a hit energy, set red, green and blue to the color we want to display
26 // for the hit. If "active" is true, set a brighter color. This is intended
27 // for when the user has moused over the cell.
28 static void colorhit(const int32_t adc, float & red, float & green, float & blue,
29  const bool active)
30 {
31  const float graycut = 85;
32 
33  const float mingray = 0.02, maxgray = 0.3;
34 
35  if(adc < graycut) red = green = blue = mingray + (maxgray - mingray)*(adc/graycut);
36  else if(adc < 600) blue = 1.0, red = 0.2, green = 0.3;
37  else if(adc < 1400) green = 1, red = blue = 0;
38  else red = 1, green = blue = 0;
39 
40  // Brighten this hit while trying to retain some of its original color, but
41  // just make it white if that is what it takes to make a difference.
42  if(active){
43  const float goal = 1.3;
44  const float left = 3 - red - blue - green;
45  if(left < goal){
46  red = blue = green = 1;
47  }
48  else{
49  red += goal*(1 - red)/left;
50  blue += goal*(1 - blue)/left;
51  green += goal*(1 - green)/left;
52  }
53  }
54 }
55 
56 // Draw a single hit to the screen, taking into account whether it is the
57 // "active" hit (i.e. being moused over right now).
58 void draw_hit(cairo_t * cr, const hit & thishit, GtkWidget ** edarea)
59 {
60  const noe_view_t V = thishit.plane%2 == 1?kX:kY;
61 
62  // Get position of upper left corner. If the zoom carries this hit entirely
63  // out of the view in screen y, don't waste cycles displaying it.
64  const int screenx = det_to_screen_x(thishit.plane);
65  if(screenx+pixx < 0) return;
66  if(screenx > edarea[V]->allocation.width) return;
67 
68  const int screeny = det_to_screen_y(thishit.plane, thishit.cell);
69  if(screeny+pixy < 0) return;
70  if(screeny > edarea[V]->allocation.height) return;
71 
72  float red, green, blue;
73 
74  colorhit(thishit.adc, red, green, blue,
75  thishit.plane == active_plane && thishit.cell == active_cell);
76 
77  cairo_set_source_rgb(cr, red, green, blue);
78 
79  // If we're representing cells with a very small number of pixels,
80  // draw all the way across to the next plane in the view to be easier
81  // to look at. If cells are visually large, make them closer to the
82  // actual size of the scintillator.
83  // XXX how about a yexpand to show the scintillator size in y?
84  // XXX are tracks correctly aligned with hits in both expanded and unexpanded
85  // styles? (Probably not!)
86  const bool xexpand = pixx <= 3;
87  const int epixx = xexpand?pixx:scintpix_from_pixx(pixx);
88 
89  // This is the only part of drawing an event that takes any time
90  // I have measured drawing a line to be twice as fast as drawing a
91  // rectangle of width 1, so it is totally worth it to have a special
92  // case. This really helps with drawing big events.
93  if(pixy == 1){
94  cairo_move_to(cr, screenx, screeny+0.5);
95  cairo_line_to(cr, screenx+epixx, screeny+0.5);
96  cairo_stroke(cr);
97  }
98  // This is a smaller gain, but it is definitely faster by about 10%.
99  else if(pixy == 2){
100  cairo_move_to(cr, screenx, screeny+0.5);
101  cairo_line_to(cr, screenx+epixx, screeny+0.5);
102  cairo_move_to(cr, screenx, screeny+1.5);
103  cairo_line_to(cr, screenx+epixx, screeny+1.5);
104  cairo_stroke(cr);
105  }
106  else{
107  cairo_rectangle(cr, screenx+0.5, screeny+0.5,
108  epixx-1, pixy-1);
109  cairo_fill(cr);
110  }
111 }
112 
113 
114 // Draw all the hits in the event that we need to draw, depending on
115 // whether we are animating or have been exposed, etc.
116 void draw_hits(cairo_t ** cr, const DRAWPARS * const drawpars, GtkWidget ** edarea)
117 {
118  if(theevents[gevi].hits.empty()) return;
119 
120  for(int i = 0; i < kXorY; i++) cairo_set_line_width(cr[i], 1.0);
121 
122  std::vector<hit> & THEhits = theevents[gevi].hits;
123 
124  std::sort(THEhits.begin(), THEhits.end(), by_charge);
125 
126  const int big = 100000;
127  const bool bigevent = THEhits.size() > big;
128 
129  int ndrawn = 0;
130  for(unsigned int i = 0; i < THEhits.size(); i++){
131  const hit & thishit = THEhits[i];
132 
133  if(thishit.tdc < drawpars->firsttick ||
134  thishit.tdc > drawpars->lasttick) continue;
135 
136  if(bigevent && (++ndrawn)%big == 0)
137  set_eventn_status_progress(ndrawn, THEhits.size());
138 
139  draw_hit(cr[thishit.plane%2 == 1?kX:kY], thishit, edarea);
140  }
141 }
142 
GtkWidget * edarea[kXorY]
Definition: drawing.cxx:20
int pixy
Definition: geo.cxx:24
static bool by_charge(const hit &a, const hit &b)
Definition: hits.cxx:15
int pixx
Definition: geo.cxx:24
Supply basic geometry functions.
void set_eventn_status_progress(const int nhit, const int tothits)
Definition: status.cxx:187
Definition: geo.h:1
uint16_t plane
Definition: event.h:2
void red()
Definition: red.C:20
int active_plane
Definition: main.cxx:78
int32_t tdc
Definition: event.h:5
uint16_t cell
Definition: event.h:2
int gevi
Definition: main.cxx:76
const Var kY([](const caf::SRProxy *sr){float tmp=0.f;if(sr->mc.nu.empty()) return tmp;tmp=sr->mc.nu[0].y;return tmp;})
__attribute__((unused)) static bool by_time(const hit &a
void hits()
Definition: readHits.C:15
tuple blue
Definition: rootlogon.py:65
std::vector< noeevent > theevents
Definition: noe_module.cc:28
void draw_hits(cairo_t **cr, const DRAWPARS *const drawpars, GtkWidget **edarea)
Definition: hits.cxx:116
const double a
int16_t adc
Definition: event.h:3
int active_cell
Definition: main.cxx:78
int det_to_screen_y(const int plane, const int cell)
Definition: geo.cxx:119
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:104
void draw_hit(cairo_t *cr, const hit &thishit, GtkWidget **edarea)
Definition: hits.cxx:58
static void colorhit(const int32_t adc, float &red, float &green, float &blue, const bool active)
Definition: hits.cxx:28
Definition: structs.h:12
Definition: geo.h:1
const hit & b
Definition: hits.cxx:21
int scintpix_from_pixx(const int x)
Definition: geo.cxx:61
int det_to_screen_x(const int plane)
Definition: geo.cxx:100
noe_view_t
Definition: geo.h:1
int32_t firsttick
Definition: drawing.h:4
int32_t lasttick
Definition: drawing.h:4