#include "global.h" //To compile : g++ AD.cxx -o {Input Executable Name} -lX11 // VERSION : 1.0 // Created with thanks to Daniel Folds Holt - University of Cambridge Cavendish Lab using namespace std; class HistoGUI{ public: HistoGUI(){} Display * disp; Window wind; XEvent evt; int screen; XColor xcolour; XColor xcolour_red; XColor xcolour_veryred; Colormap cmap; std::vector x; std::vector y; std::vector y_errors; double max_x; double min_x; double max_y; double min_y; double pos_x; double pos_y; double new_pos_x; double new_pos_y; unsigned int width; unsigned int height; double window_width; double window_height; double width_scale; double x_offset; double height_scale; double y_offset; double A0; double A2E; double A4E; int SetFit(double a, double b, double c){ A0 = a; A2E = b; A4E = c; fit_exists = true; return 1; } double old_xl, old_xh, old_yl, old_yh; double old_mouse_x, old_mouse_y; int Init(); int SetData(std::vector a, std::vectorb); int SetErrors(std::vector a); int Loop(); void Close(){ printf("Closing now!\n"); XCloseDisplay(disp); } int DrawData(double x_low_win, double y_low_win, double x_hi_win, double y_hi_win); int Draw_Fit(double x_low_win, double y_low_win, double x_hi_win, double y_hi_win); int DrawCrosshairs(int mouse_x, int mouse_y); int Zoom(int mouse_x, int mouse_y); double legval(double theta); bool fit_exists = false; // int Legendre_fit(std::vector d1, std::vector d2, double }; int HistoGUI::SetData(std::vector a, std::vectorb){ for(int i=0; i < a.size(); i++){ x.push_back(a[i]); y.push_back(b[i]); } return a.size(); } int HistoGUI::SetErrors(std::vector a){ for(int i=0; i < a.size(); i++){ y_errors.push_back(a[i]); } return a.size(); } int HistoGUI::Init(){ disp = XOpenDisplay(NULL); if (disp == NULL) { fprintf(stderr, "Cannot open display\n"); exit(1); } //fit_exists = false; screen = DefaultScreen(disp); wind = XCreateSimpleWindow(disp, RootWindow(disp, screen), 10, 10, 600, 400, 1, BlackPixel(disp, screen), WhitePixel(disp, screen)); XGrabPointer(disp, wind, False, ButtonPressMask | ButtonReleaseMask | PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); XSelectInput(disp, wind, ExposureMask | KeyPressMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask); XMapWindow(disp, wind); // colours cmap = DefaultColormap(disp, screen); xcolour.red = 32000; xcolour.green = 32000; xcolour.blue = 42000; xcolour.flags = DoRed | DoGreen | DoBlue; XAllocColor(disp, cmap, &xcolour); xcolour_red.red = 42000; xcolour_red.green = 32000; xcolour_red.blue = 32000; xcolour_red.flags = DoRed | DoGreen | DoBlue; XAllocColor(disp, cmap, &xcolour_red); xcolour_veryred.red = 65000; xcolour_veryred.green = 32000; xcolour_veryred.blue = 32000; xcolour_veryred.flags = DoRed | DoGreen | DoBlue; XAllocColor(disp, cmap, &xcolour_veryred); return 1; } int HistoGUI::DrawCrosshairs(int mouse_x, int mouse_y){ int j1, j2; unsigned int j3, j4; Window root_return; XGetGeometry(disp, wind, &root_return, &j1, &j2, &width, &height, &j3, &j4); XSetForeground(disp, DefaultGC(disp, screen), xcolour_red.pixel); XDrawLine(disp, wind, DefaultGC(disp, screen), mouse_x, 0.0, mouse_x, height); XDrawLine(disp, wind, DefaultGC(disp, screen), 0.0, mouse_y, width, mouse_y); pos_y = mouse_y * height_scale - y_offset; pos_x = mouse_x * width_scale - x_offset; char coord[32]; sprintf(coord, "(%.2f, %.2f)", pos_x, pos_y); XDrawString(disp, wind, DefaultGC(disp, screen), mouse_x + 5, mouse_y + 12, coord, strlen(coord)); return 1; } int HistoGUI::Zoom(int mouse_x, int mouse_y){ new_pos_x = mouse_x * width_scale - x_offset; new_pos_y = mouse_y * height_scale - y_offset; pos_x = old_mouse_x * width_scale - x_offset; pos_y = old_mouse_y * height_scale - y_offset; if(std::abs(mouse_x - old_mouse_x) < 20 or std::abs(mouse_y - old_mouse_y) < 20) return 1; //printf("Zooming: %f - %f, %f - %f\n", mouse_x, old_mouse_x,mouse_y,old_mouse_y); double x_low_win, y_low_win, x_hi_win, y_hi_win; if(new_pos_x < pos_x){ x_low_win = new_pos_x; x_hi_win = pos_x; //printf("new low; [%f, %f]\n",x_low_win, x_hi_win); } else { x_low_win = pos_x; x_hi_win = new_pos_x; //printf("new high; [%f, %f]\n",x_low_win, x_hi_win); } if(new_pos_y > pos_y){ y_low_win = new_pos_y; y_hi_win = pos_y; } else { y_low_win = pos_y; y_hi_win = new_pos_y; } //printf("[(%f,%f) (%f,%f)]\n",x_low_win, y_low_win, x_hi_win, y_hi_win); XClearWindow(disp, wind); DrawData(x_low_win, y_low_win, x_hi_win, y_hi_win); //double x_low_win, double y_low_win, double x_hi_win, double y_hi_win return 1; } double HistoGUI::legval(double theta){ double lg; double aaa = A0/A0; double aab = (A2E/A0)*(1.5 * pow(cos(theta),2) - .5); double aac = (A4E/A0)*(35./8. * pow(cos(theta),4) - 30./8. * pow(cos(theta),2) + 3./8. ); lg = aaa + aab + aac; return lg; } int HistoGUI::Draw_Fit(double x_low_win, double y_low_win, double x_hi_win, double y_hi_win){ int j1, j2; unsigned int j3, j4; Window root_return; XGetGeometry(disp, wind, &root_return, &j1, &j2, &width, &height, &j3, &j4); //printf("Width = %u, Height = %u, x = %i, y = %i\n", width, height, j1, j2); //printf("[(%f,%f) (%f,%f)]\n",x_low_win, y_low_win, x_hi_win, y_hi_win); double x_step;// = (width * 0.8) / x.size(); double y_step;// = (height * 0.8) / x.size(); if(x_low_win == -1 and y_low_win == -1 and x_hi_win == -1 and y_hi_win == -1){ // Audomatically decide data postition max_x = x[0]; max_y = y[0]; min_x = x[0]; min_y = y[0]; for(int i=0; i max_x) max_x = x[i]; if(x[i] < min_x) min_x = x[i]; if(y[i] > max_y) max_y = y[i]; if(y[i] < min_y) min_y = y[i]; } width_scale = (max_x - min_x) / (0.8 * width); x_offset = 0.5 * ((max_x - min_x) / 0.8) - 0.5 * (min_x + max_x); height_scale = -1. * (max_y - min_y) / (0.8 * height); y_offset = -0.5 * ((max_y - min_y) / 0.8) + -0.5 * (min_y + max_y); XSetForeground(disp, DefaultGC(disp,screen), xcolour_red.pixel); double x_wid ; double y_wid ; for(int i=0; i < (int) width; i += 2){ double x_val = i * width_scale - x_offset; double y_val = legval(x_val); y_wid = (y_val + y_offset) / height_scale; XFillRectangle(disp, wind, DefaultGC(disp, screen), i -2, y_wid -2, 4, 4); } // XFillRectangle(disp, wind, DefaultGC(disp, screen), x_wid2 -2, y_wid2 -2, 4, 4); } else { //double x_low_win, double y_low_win, double x_hi_win, double y_hi_win width_scale = (x_hi_win - x_low_win) / width; x_offset = -1.0 * x_low_win; height_scale = (y_hi_win - y_low_win) / height; y_offset = -1.0 * y_low_win; XSetForeground(disp, DefaultGC(disp,screen), xcolour_red.pixel); double x_wid ; double y_wid ; for(int i=0; i < (int) width; i += 2){ double x_val = i * width_scale - x_offset; double y_val = legval(x_val); y_wid = (y_val + y_offset) / height_scale; XFillRectangle(disp, wind, DefaultGC(disp, screen), i -2, y_wid -2, 4, 4); } } old_xl = x_low_win; old_yl = y_low_win; old_xh = x_hi_win; old_yh = y_hi_win; return 1; } int HistoGUI::DrawData(double x_low_win, double y_low_win, double x_hi_win, double y_hi_win){ if(fit_exists){ Draw_Fit(x_low_win,y_low_win,x_hi_win,y_hi_win); } int j1, j2; unsigned int j3, j4; Window root_return; XGetGeometry(disp, wind, &root_return, &j1, &j2, &width, &height, &j3, &j4); //printf("Width = %u, Height = %u, x = %i, y = %i\n", width, height, j1, j2); //printf("[(%f,%f) (%f,%f)]\n",x_low_win, y_low_win, x_hi_win, y_hi_win); double x_step;// = (width * 0.8) / x.size(); double y_step;// = (height * 0.8) / x.size(); if(x_low_win == -1 and y_low_win == -1 and x_hi_win == -1 and y_hi_win == -1){ // Audomatically decide data postition max_x = x[0]; max_y = y[0]; min_x = x[0]; min_y = y[0]; for(int i=0; i max_x) max_x = x[i]; if(x[i] < min_x) min_x = x[i]; if(y[i] > max_y) max_y = y[i]; if(y[i] < min_y) min_y = y[i]; } //printf(" max_x = %f\n", max_x ); //printf(" max_y = %f\n", max_y ); //printf(" min_x = %f\n", min_x ); //printf(" min_y = %f\n", min_y ); width_scale = (max_x - min_x) / (0.8 * width); x_offset = 0.5 * ((max_x - min_x) / 0.8) - 0.5 * (min_x + max_x); height_scale = -1. * (max_y - min_y) / (0.8 * height); y_offset = -0.5 * ((max_y - min_y) / 0.8) + -0.5 * (min_y + max_y); //printf("width scale = %f\n", width_scale); //printf("x_offset = %f\n", x_offset); //printf("height scale = %f\n", height_scale); //printf("y_offset = %f\n", y_offset); double axis_x = (0. + x_offset) / width_scale; double axis_y = (0. + y_offset) / height_scale; //cout << "x-axis = %lf\n" <