/**************************************************************************** * * root_GUI.cc -- A program to display OBJY DB information graphically * for HV testing * This program includes the ROOT and OBJY libraries to make use of * both. * * * This program was developed for the PHENIX Experiment at Brookhaven * National Laboratory, by a Los Alamos National Laboratory employee. * Coypright 1998 Los Alamos National Laboratory, USA. * * * * R. Roth October 1998 **************************************************************************** */ /***************************************************************************** * FUNCTIONALITY VERSION 1.10 ***************************************************************************** * * This program, root_GUI, can accept 2 command line arguments. The 1st is * the name of a Database, which it will immediately load. Without the * argument, it loads a default database, DEMO. The second argument, if * given, instructs the program to load a named configuration file. The * configuration files used by this program are plain ASCII files that end * with .DPC (Display Program Configuration). These files hold information * that related to how the histograms and graphs are displayed on the canvas. * * This program generates 2 windows: a large canvas drawing area and a * command window. By selecting options in the command window and clicking * one of the draw buttons, a group of graphs and/or histograms will be * displayed to the canvas window. * * THE CANVAS WINDOW: * This window is constructed as a standard ROOT canvas. As such, it has * the ROOT canvas toolbar. From this toolbar it is possible to save * canvas as a .gif, .ps or .eps file, view the colors and markers available, * and several other things. Since this program is built as a 'Stand-Alone' * type and does not operate out of ROOT's cint, you may find that some * of the toolbar options do not work. * * THE COMMAND WINDOW: * This window consists of five tabs, a menu bar, and a bar of selection * boxes and buttons (the 'Button Bar'). * * TAB 1 -- Plotting * From here, you can select a new database and channel to plot, by * typing a new DB name in the labeled text field. * Channel Selection is done by clicking on one of the channel listings * that appear in the listbox. The program fills this listbox whenever * a carriage return is typed in the DB Name text field or when the * 'Load Channels' button is pressed. By selecting channels in this way, * it becomes impossible to select a channel which does not exist in the * current database. Loading channels requires that the database be * opened and closed. When one of the channels is clicked, its name * appears in the opposite list box. You can select several channels, or * even even the same channel multiple times. When the 'Draw!' button in * the button bar is clicked, the program takes the channels listed here as * draws them all to the canvas, which is split into an appropriate number * of sections. Channels can be removed from the second list box by clicking * them. Note that, when a channel is removed, the next channel selected fills * its spot rather than being appended to the end of the list. That is, if * there are 4 channels in the list box, and the second one is removed, then * the next channel selected will fill the second slot rather than the fourth or * fifth one. * * TAB 2 -- 1D Histogram * From here, options regarding the style, type and appearance of the * 1D Histograms generated by pressing the 'Draw Histogram' button. There * are 4 histogram types: Voltage, Current, Demand Voltage and Voltage/ * Demand Voltage; each type histograms a different Readback parameter. * final type is actually 2 histograms, the Demand Voltage Histogram overlayed * onto the Voltage histogram. From this tab, you can change the colors used * to draw the lines and fill areas of one or both histograms by selecting * one of the six colors in the appropriate listbox. You can also select one * of 5 marker styles, and one of 5 error bar options. * Finally, there are also five Drawing options which change the style of the * plot. Some of these are incompatable -- for example, the program * ignores the 'Bar Graph' option if the 'Plot Lego Style' is set. Some * of the incompatiablites don't make too much sense (i.e., it is impossible, * from what I can tell, to have a Smooth curve with Markers) -- the * source of the problem lies in the ROOT libraries, and not in this program. * NOTE: If a lego plot is selected as well as Voltage/Demand Voltage, the * program only displays the voltage portion of the plot, since if it did * otherwise the plots drawn would overlap and look very strange. * NOTE2: When the histogram is drawn (a non-lego version) a box containing * staticistical information is drawn as well. Note that the Mean and RMS * values listed here are computed strictly from the number of Readbacks and * that parmeter's values. For example, the RMS listed on a Voltage histogram * IN NO WAY is computed from the Demand Voltage data. * NOTE3: When you make a change to anything in this tab, the program updates * the configuration for the pad number listed in the button bar. Changing to * a different pad with a different configuration immediately updates this Tab. * The configuration saves information related to the 1D Histograms for every pad, * even if the pads describe 2D Histograms or Graphs. This way, if the pad is * changed to a 1D Histogram, no additional updates need to be performed. * * TAB 3 -- Graph * This is similiar to the previous tab, expect that it defines graph, * rather than histogram, parameters. The graphs display Readback variables * vs. time; in addition to Voltage, Current, and Demand Voltage, the * graphs can also plot the channel Status and Enable information. * You can change the color of the graph line, canvas background, fill area, * and graph background. The drawing options are similiar to the ones on * the previous tab. Remember that the 'Bar Graph' option draws the bars from * the Y=0 line, which may not be on the graph. Like in the previous tab, * you can select from 5 types of Markers. * NOTE: For some reason, the ROOT libraries (at least with my setup) cause a * segmentation fault if no options are given, or if only the axis option * (which this program adds autmatically) is used. This being the case, I have * made sure the user selects at least one of the options before the program attempts * to graph it. * * TAB 4 -- 2D Histograms * This tab contains the radio buttons and checkboxes which control the style * and appearance of the 2D histograms. You can choose to plot Voltage against * Current or Demand Voltage, Demand Voltage against Current, or any of these * values over time. There are 15 possible styles of 2D Histogram plotting * available. In addition, for Surface and Lego plots, you can choose to * conceal the front and/or back portion of the wire frame in which the plot is * constructed. * NOTE: The 'Surface 5' cooresponds to Gouraud Shading. This program sometimes * paints a completely white surface when this option is selected, which is not * very useful. This is caused by other programs taking up memory and/or colormaps. * If you need this option, make sure to close other windows-based applications * especially Netscape. * NOTE2: Some of the styles draw correctly, but just aren't to useful. They have * been left in for educational purposes, and because it's a pain to remove them :) * * TAB 5 -- Histogram Options * From this tab you select what portions of the 1D and 2D histograms are visible * in the canvas. You can change the number of bins for each axis and the range * of values. The histograms center on the average of the parameter, and extend * +/- the range entered. The Voltage range is used for both Voltage and * Demand Voltage parmeters, and the Current range is used for the Current parmeter. * In 2D histogram plots with time, the time range starts at 0 and extends to the * last time in the Readback list, with a number of bins equal to the number of * Readbacks associated with this channel. * NOTE: With 2D histograms, it is usually better to use a smaller number of bins * so that the plot is constructed faster and is more readable. * * BUTTON BAR * This bar holds two buttons and two selection boxes. The buttons control drawing to * canvas and exiting the program. The Pad selection box is a new feature which * allows the user to draw multiple histograms with different appearences and styles. * Each pad has a configuration in memory which describes its style -- this * configuration can be altered by choosing the right pad in the slection box, then * changing the information on Tabs 2, 3, 4, and 5. In addition, you can use the * 'Plot Type' selection box to choose between a Graph, a 1D or a 2D Histogram. * * MENU BAR * This bar currently only has one pop-up menu. From this menu, you can save to a file * the pad configuration, so that it may be loaded later, saving you time. Configuration * files must have a .DPC extension. You need not type this when saving the configuration; * it is added automatically. You can also close the menu and exit the program from here. * * * SPEEDY ACCESS * I have designed this program anticipating the need of a user to quickly go through a * database's channels and view certain characteristics for each. The best way to do this * is to set up the graph/histogram options, then switch to the 'Plotting' tab. From here, * you can select each channel quickly with a mouse click, then hit the Draw button. This * makes for fairly rapid scanning of the entire database, as well as the capability to * switch back and forth between channels with only a few mouse clicks. Once you have constructed * a few common configurations, you can also quickly view several channels or attributes at once. * * OBJECTS IN MEMORY * When a Histogram or graph is drawn, the object is kept in memory purposefully. This * allows the user to move the contents of the canvas around with the mouse. For Lego * and Surface plots, the plot can be rotated to provide a better view. If the objects * are deleted after they are drawn, the picture will remain, but clicking anywhere * in the canvas will cause the plot to disappear. * * NETSCAPE NOTE * If Netscape is active when this program is run, this program will not be able to select * and use many of the normal colors. Netscape can use a command line option to prevent * it from eating the colormaps completely, but I don't recall exactly what it is. I have * selected as selectable colors those colors which seem to be available regardless of * whether Netscape is running. If you run this program and see much more white than usual, * close Netscape! * * * Ryan Roth * 14 December 1998 * * LATEST IMPROVEMENT -- 12/16/98 * I've added to Tab #1 a matrix of buttons. These buttons, when pressed, create a new, * large canvas and plot the corresponding pad number to it. In this way, the user can * enlarge the smaller plots found on the main canvas to make them more readable. This * allows you to use the main canvas as a thumbnail index. The new buttons are disabled * until after the 'Draw!!' button is pressed -- this prevents the case where the new canvas * has old data plotted to it. * RR * 12/17/98 * I fixed a few problems with the 'Load Channels' function and expanded the command line * arguments. Now you can select a database with a -db flag, a configuration file with a * -cf flag, or get the usage with a -help flag. * * 1/6/99 * Our machines now can use Root version 2.20.06. I tested the software and discovered no * problems. Now it is possible, for any given Graph or Histogram, to zoom in to a specifc area * covered by the axis. This is done by left-clicking the axis, and then dragging over the axis * to created the new zoomed in area. Zooming out is more difficult -- apparently you have to * create the zoomed in area that extends past the edge of the plot. It's easier just to redraw * the plot. * RR * * 1/27/99 * Modified LoadChannels() slightly so that it doesn't waste so much time confirming that * there are no channels left to check and list. * RR * **/ /* feature test switches */ #define _POSIX_C_SOURCE 199506L /* system headers -- For Objectivity*/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // just to get the STL headers #include "dbhv_mainframe.h" #include "dbhv_module.h" #include "dbhv_channel.h" #include "dbhv_setpoint.h" #include "dbhv_readback.h" /* Headers for ROOT */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //#include //#include #include //#include #include #include #include #include //#include #include #include //#include #include #include #define MAX_NUM_READBACKS 4096 #define MAX_PADS 9 enum EMessageID { M_FILE_OPEN, M_FILE_SAVE, M_FILE_EXIT, B_DRAW, B_QUIT, B_LOAD_CHAN, B_PRINT, B_MAX1, B_MAX2, B_MAX3, B_MAX4, B_MAX5, B_MAX6, B_MAX7, B_MAX8, B_MAX9 }; const char *filetypes[] = { "HVDP Configuration files", "*.DPC", "All files", "*", 0, 0 }; /////////////////////////////////////////////////////////////////////// // Class to define a ROOT version of the HV Readback // // needed for sorting and graphing // /////////////////////////////////////////////////////////////////////// class TRootReadback : public TObject { //This class sorts by referencing the time the readback was taken, // since it is highly unlikely that two readbacks would have the same // timestamp. private: int iEnabled; int iStatus; double dDemandVoltage; double dVoltage; double dCurrent; time_t time; public: TRootReadback(int enable, int status, double demand, double current, double voltage, struct tm *stamp); ~TRootReadback(); int getEnable() {return iEnabled;} int getStatus() {return iStatus;} double getDemandVoltage() {return dDemandVoltage;} double getVoltage() {return dVoltage;} double getCurrent() {return dCurrent;} void Print(Option_t* option) { cout << "RB: Voltage = " << dVoltage << " Current = " << dCurrent; cout << " Time = " << time << endl; } time_t getTime() {return time;} ULong_t Hash() {return (ULong_t)time;} Bool_t IsEqual(TObject *obj) { return (((TRootReadback*)obj)->time == time);} Bool_t IsSortable() const {return kTRUE;} Int_t Compare(TObject *obj) { if (time > ((TRootReadback*)obj)->time) return 1; else if (time < ((TRootReadback*)obj)->time) return -1; else return 0; } }; TRootReadback::TRootReadback(int enable, int status, double demand, double current, double voltage, struct tm *stamp) { iEnabled = enable; iStatus = status; dDemandVoltage = demand; dVoltage = voltage; dCurrent = current; time = mktime(stamp); } TRootReadback::~TRootReadback() {} /////////////////////////////////////////////////////////////////////// // Configuation Object that holds the information which // // describes what plot goes on what pad. // /////////////////////////////////////////////////////////////////////// class TConfiguration : public TObject { private: Int_t PlotKind[MAX_PADS]; // 1D, Graph, or 2D histogram Int_t Type1D[MAX_PADS]; // Voltage, Current, DV, etc. Int_t TypeGraph[MAX_PADS]; // V vs time, C vs time, etc. Int_t Type2D[MAX_PADS]; // V vs C, C vs DV, etc. Int_t PlotSubType[MAX_PADS]; // For 2D Histograms only -- Box, Lego, Scatter, etc. Int_t Plot1DOptions[MAX_PADS]; // Bar Graph, Smooth Curve, Lego, etc. Int_t PlotGrfOptions[MAX_PADS]; // Bar Graph, Smooth Curve, etc. Int_t Plot2DOptions[MAX_PADS]; // Conceal Front Box, back box Color_t Line_Color1[MAX_PADS]; // 1D -- line color Color_t Fill_Color1[MAX_PADS]; // 1D -- Fill Color Color_t Line_Color2[MAX_PADS]; // 1D -- 2nd line color Color_t Fill_Color2[MAX_PADS]; // 1D -- 2nd fill color Int_t MarkerStyle1D[MAX_PADS]; // 1D -- Circles, Crosses, etc. Color_t GraphLine[MAX_PADS]; // Graph -- Line Color Color_t GraphFill[MAX_PADS]; // Graph -- Fill Color Color_t GraphCanvas[MAX_PADS]; // Graph -- Canvas Color Color_t GraphBG[MAX_PADS]; // Graph -- BG Color Int_t GraphMarker[MAX_PADS]; // Graph -- Marker style Int_t ErrorBars[MAX_PADS]; // 1D -- Error Bar Type Int_t Num1DBins[MAX_PADS]; // 1D -- Number of Bins in Histogram Int_t Num2DXBins[MAX_PADS]; // 2D -- # bins on x axis Int_t Num2DYBins[MAX_PADS]; // 2D -- # bins on y axis Float_t Volt1DRange[MAX_PADS]; // 1D -- Voltage Range Float_t Curr1DRange[MAX_PADS]; // 1D -- Current Range Float_t Volt2DRange[MAX_PADS]; // 2D -- Voltage Range Float_t Curr2DRange[MAX_PADS]; // 2D -- Current Range public: TConfiguration(); ~TConfiguration() {;} int PrintConfig(int i); int PrintAllConfigs(); void SetPlotKind( int index, Int_t value) { PlotKind[index] = value; } void SetType1D( int index, Int_t value) { Type1D[index] = value; } void SetTypeGraph( int index, Int_t value) { TypeGraph[index] = value; } void SetType2D( int index, Int_t value) { Type2D[index] = value; } void SetPlotSubType( int index, Int_t value) { PlotSubType[index] = value; } void SetPlot1DOptions( int index, Int_t value) { Plot1DOptions[index] = value; } void SetPlotGrfOptions( int index, Int_t value) { PlotGrfOptions[index] = value; } void SetPlot2DOptions( int index, Int_t value) { Plot2DOptions[index] = value; } void SetLine1( int index, Color_t value) { Line_Color1[index] = value; } void SetFill1( int index, Color_t value) { Fill_Color1[index] = value; } void SetLine2( int index, Color_t value) { Line_Color2[index] = value; } void SetFill2( int index, Color_t value) { Fill_Color2[index] = value; } void SetMarker( int index, Int_t value) { MarkerStyle1D[index] = value; } void SetGraphLine( int index, Color_t value) { GraphLine[index] = value; } void SetGraphFill( int index, Color_t value) { GraphFill[index] = value; } void SetGraphCanvas( int index, Color_t value) { GraphCanvas[index] = value; } void SetGraphBG( int index, Color_t value) { GraphBG[index] = value; } void SetGraphMarker( int index, Int_t value) { GraphMarker[index] = value; } void SetErrorBars( int index, Int_t value) { ErrorBars[index] = value; } void SetNum1DBins( int index, Int_t value) { Num1DBins[index] = value; } void SetNum2DXBins( int index, Int_t value) { Num2DXBins[index] = value; } void SetNum2DYBins( int index, Int_t value) { Num2DYBins[index] = value; } void SetVolt1D( int index, Float_t value) { Volt1DRange[index] = value; } void SetCurr1D( int index, Float_t value) { Curr1DRange[index] = value; } void SetVolt2D( int index, Float_t value) { Volt2DRange[index] = value; } void SetCurr2D( int index, Float_t value) { Curr2DRange[index] = value; } Int_t GetPlotKind( int index) { return PlotKind[index]; } Int_t GetType1D( int index) { return Type1D[index]; } Int_t GetTypeGraph( int index) { return TypeGraph[index]; } Int_t GetType2D( int index) { return Type2D[index]; } Int_t GetPlotSubType( int index) { return PlotSubType[index]; } Int_t GetPlot1DOptions( int index) { return Plot1DOptions[index]; } Int_t GetPlotGrfOptions( int index) { return PlotGrfOptions[index]; } Int_t GetPlot2DOptions( int index) { return Plot2DOptions[index]; } Color_t GetLine1( int index) { return Line_Color1[index]; } Color_t GetFill1( int index) { return Fill_Color1[index]; } Color_t GetLine2( int index) { return Line_Color2[index]; } Color_t GetFill2( int index) { return Fill_Color2[index]; } Int_t GetMarker1D( int index) { return MarkerStyle1D[index]; } Color_t GetGraphLine( int index) { return GraphLine[index]; } Color_t GetGraphFill( int index) { return GraphFill[index]; } Color_t GetGraphCanvas( int index) { return GraphCanvas[index]; } Color_t GetGraphBG( int index) { return GraphBG[index]; } Int_t GetGraphMarker( int index) { return GraphMarker[index]; } Int_t GetErrorBars( int index) { return ErrorBars[index]; } Int_t GetNum1DBins( int index) { return Num1DBins[index]; } Int_t GetNum2DXBins( int index) { return Num2DXBins[index]; } Int_t GetNum2DYBins( int index) { return Num2DYBins[index]; } Float_t GetVolt1D( int index) { return Volt1DRange[index]; } Float_t GetCurr1D( int index) { return Curr1DRange[index]; } Float_t GetVolt2D( int index) { return Volt2DRange[index]; } Float_t GetCurr2D( int index) { return Curr2DRange[index]; } }; TConfiguration::TConfiguration() { // LOAD DEFAULT CONFIGURATION for (int i = 0; iGetRoot()); fMenuFile->AddEntry("&Open Configuration File...", M_FILE_OPEN); fMenuFile->AddEntry("&Save Configuration File...", M_FILE_SAVE); fMenuFile->AddSeparator(); fMenuFile->AddEntry("&Close", -1); fMenuFile->AddEntry("&Exit", M_FILE_EXIT); fMenuFile->Associate(this); fMenuBar = new TGMenuBar(this, 1, 1, kHorizontalFrame | kRaisedFrame); fMenuBar->AddPopup("&File", fMenuFile, new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0)); AddFrame(fMenuBar, new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX, 0, 0, 1, 1)); // Set up and layout Close and Draw Button Bar // SOME COMMON LAYOUTS TGLayoutHints *fL1 = new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX, 2, 2, 2, 2); TGLayoutHints *fL2 = new TGLayoutHints(kLHintsBottom | kLHintsRight, 2, 2, 5, 1); TGLayoutHints *fL3 = new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 5, 5); TGLayoutHints *fL4 = new TGLayoutHints(kLHintsTop | kLHintsRight, 5, 5, 5, 5); TGLayoutHints *fL5 = new TGLayoutHints(kLHintsCenterY | kLHintsLeft | kLHintsExpandX, 2, 2, 0, 0); fButtonFrame = new TGHorizontalFrame(this, 400, 20, kFixedWidth); fPadBox = new TGComboBox(fButtonFrame, 300); fPlotKindBox = new TGComboBox(fButtonFrame, 301); TGLabel *padlab = new TGLabel(fButtonFrame, new TGString("Pad #: ")); TGLabel *kindlab = new TGLabel(fButtonFrame, new TGString("Plot Type: ")); fCloseButton = new TGTextButton(fButtonFrame, "&Quit", B_QUIT); fCloseButton->Associate(this); fCloseButton->SetToolTipText("Closes and exits program"); fDrawButton = new TGTextButton(fButtonFrame, "&Draw!!", B_DRAW); fDrawButton->Associate(this); fDrawButton->SetToolTipText("Draw All Plots!"); fButtonFrame->AddFrame(padlab, fL5); fButtonFrame->AddFrame(fPadBox, new TGLayoutHints(kLHintsCenterY | kLHintsLeft, 0, 0, 0, 0)); fButtonFrame->AddFrame(kindlab, new TGLayoutHints(kLHintsCenterY | kLHintsLeft, 5, 0, 0, 0)); fButtonFrame->AddFrame(fPlotKindBox, new TGLayoutHints(kLHintsCenterY | kLHintsLeft, 0, 5, 0, 0)); fButtonFrame->AddFrame(fDrawButton, fL5); fButtonFrame->AddFrame(fCloseButton, fL5); AddFrame(fButtonFrame, new TGLayoutHints(kLHintsBottom | kLHintsLeft, 0, 0, 0, 0)); fPadBox->Resize(60,20); fPlotKindBox->Resize(100,20); char pboxentry[10]; for (int i = 0; iAddEntry(pboxentry, i); } fPadBox->Select(0); fPlotKindBox->AddEntry("1D Histogram", 1); fPlotKindBox->AddEntry("Graph", 2); fPlotKindBox->AddEntry("2D Histogram", 3); fPlotKindBox->Select(1); fPadBox->Associate(this); fPlotKindBox->Associate(this); // TAB #1 fTab = new TGTab(this, 300, 300); TGCompositeFrame *tf = fTab->AddTab("Plotting"); //Sets up text fields fTextFrame = new TGCompositeFrame(tf, 60, 20, kVerticalFrame); TGCompositeFrame *tfDB = new TGCompositeFrame(fTextFrame, 60, 20, kHorizontalFrame); TGCompositeFrame *tfBF = new TGCompositeFrame(fTextFrame, 60, 20, kHorizontalFrame); TGLayoutHints *labhint = new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 3, 5, 0, 0); TGLayoutHints *texthint = new TGLayoutHints(kLHintsRight | kLHintsCenterY | kLHintsExpandX, 0, 2, 0, 0); TGLayoutHints *framehint = new TGLayoutHints(kLHintsTop | kLHintsExpandX, 2, 2, 3, 0); TGLabel *DBlab = new TGLabel(tfDB, new TGString("Database Name: ")); fDBNameText = new TGTextEntry(tfDB, fDBbuf = new TGTextBuffer(50), 100); Bool_t dbnamefound = kFALSE; if (argc>1) { //get database name from command line argument for (i=0; iAddText(0, argv[i+1]); dbnamefound = kTRUE; cout << endl << endl << "INITIAL DATABASE = " << argv[i+1] << endl; break; } if (!dbnamefound) { fDBbuf->AddText(0, "DEMO"); cout << endl << endl << "INITIAL DATABASE = DEMO" << endl; } } else { fDBbuf->AddText(0, "DEMO"); cout << endl << endl << "INITIAL DATABASE = DEMO" << endl; } fDBNameText->Associate(this); fDBNameText->Resize(300, fDBNameText->GetDefaultHeight()); fChannelButton = new TGTextButton(tfBF, "Load Channels", B_LOAD_CHAN); fChannelButton->SetToolTipText("List below this DB's Channels"); fChannelButton->Associate(this); fPlotMultiButton = new TGTextButton(tfBF, "Print Pad Configuration", B_PRINT); fPlotMultiButton->Associate(this); fPlotMultiButton->SetToolTipText("Print Each Pad's Configuration to Standard Output"); tfBF->AddFrame(fChannelButton, new TGLayoutHints(kLHintsLeft | kLHintsCenterY | kLHintsExpandX, 3, 5, 0, 0)); tfBF->AddFrame(fPlotMultiButton, texthint); tfDB->AddFrame(DBlab, labhint); tfDB->AddFrame(fDBNameText, texthint); fTextFrame->AddFrame(tfDB, framehint); fTextFrame->AddFrame(tfBF, framehint); tf->AddFrame(fTextFrame, fL3); //Set up List boxes TGCompositeFrame *fLB = new TGCompositeFrame(tf, 60, 20, kHorizontalFrame); TGCompositeFrame *fVF = new TGCompositeFrame(fLB, 60, 20, kVerticalFrame); TGCompositeFrame *fVFr1 = new TGCompositeFrame(fVF, 60, 20, kHorizontalFrame); TGCompositeFrame *fVFr2 = new TGCompositeFrame(fVF, 60, 20, kHorizontalFrame); TGCompositeFrame *fVFr3 = new TGCompositeFrame(fVF, 60, 20, kHorizontalFrame); fMaximize[0] = new TGTextButton(fVFr1, "1", B_MAX1); fMaximize[1] = new TGTextButton(fVFr1, "2", B_MAX2); fMaximize[2] = new TGTextButton(fVFr1, "3", B_MAX3); fMaximize[3] = new TGTextButton(fVFr2, "4", B_MAX4); fMaximize[4] = new TGTextButton(fVFr2, "5", B_MAX5); fMaximize[5] = new TGTextButton(fVFr2, "6", B_MAX6); fMaximize[6] = new TGTextButton(fVFr3, "7", B_MAX7); fMaximize[7] = new TGTextButton(fVFr3, "8", B_MAX8); fMaximize[8] = new TGTextButton(fVFr3, "9", B_MAX9); for(i=0; iSetToolTipText("Maximize this Pad"); fMaximize[i]->Associate(this); if (i!=0) fMaximize[i]->SetState(kButtonDisabled); } fVFr1->AddFrame(fMaximize[0], new TGLayoutHints(kLHintsCenterY | kLHintsLeft, 0, 0, 0, 0)); fVFr1->AddFrame(fMaximize[1], new TGLayoutHints(kLHintsCenterY | kLHintsLeft, 0, 0, 0, 0)); fVFr1->AddFrame(fMaximize[2], new TGLayoutHints(kLHintsCenterY | kLHintsLeft, 0, 0, 0, 0)); fVFr2->AddFrame(fMaximize[3], new TGLayoutHints(kLHintsCenterY | kLHintsLeft, 0, 0, 0, 0)); fVFr2->AddFrame(fMaximize[4], new TGLayoutHints(kLHintsCenterY | kLHintsLeft, 0, 0, 0, 0)); fVFr2->AddFrame(fMaximize[5], new TGLayoutHints(kLHintsCenterY | kLHintsLeft, 0, 0, 0, 0)); fVFr3->AddFrame(fMaximize[6], new TGLayoutHints(kLHintsCenterY | kLHintsLeft, 0, 0, 0, 0)); fVFr3->AddFrame(fMaximize[7], new TGLayoutHints(kLHintsCenterY | kLHintsLeft, 0, 0, 0, 0)); fVFr3->AddFrame(fMaximize[8], new TGLayoutHints(kLHintsCenterY | kLHintsLeft, 0, 0, 0, 0)); fChannelListBox = new TGListBox(fLB, 200); fChannelListBox->Resize(120, 150); fChannelListBox->Associate(this); TGLabel *LBlab = new TGLabel(fVF, new TGString(" --> Pad Selections --> " )); TGLabel *LBlab2 = new TGLabel(fVF, new TGString("Maximize Pad Number:")); fPadListBox = new TGListBox(fLB, 202); fPadListBox->Resize(120, 150); fPadListBox->Associate(this); fLB->AddFrame(fChannelListBox, fL3); fVF->AddFrame(LBlab, new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 0, 5, 5)); fVF->AddFrame(LBlab2, new TGLayoutHints(kLHintsCenterX, 0, 0, 5, 5)); fVF->AddFrame(fVFr1, new TGLayoutHints(kLHintsCenterX, 0, 0, 0, 0)); fVF->AddFrame(fVFr2, new TGLayoutHints(kLHintsCenterX, 0, 0, 0, 0)); fVF->AddFrame(fVFr3, new TGLayoutHints(kLHintsCenterX, 0, 0, 0, 0)); fLB->AddFrame(fVF, new TGLayoutHints(kLHintsCenterY | kLHintsLeft, 0, 0, 5, 5)); fLB->AddFrame(fPadListBox, fL4); tf->AddFrame(fLB, fL3); //TAB # 2 tf = fTab->AddTab("1D Histogram"); /// 6 labels, 6 combo boxes, 5 checkboxes, 4 radiobuttons //NOTE: I have used many 'temporary' Composite frames to layout the widgets // nicely. The naming conventions for them is: t#cf# or t#gf#, which // means 'tab #, composite frame #' and 'tab #, group frame #' TGCompositeFrame *tab2 = new TGCompositeFrame(tf, 60, 20, kVerticalFrame); TGCompositeFrame *t2cf1 = new TGCompositeFrame(tab2, 60, 20, kHorizontalFrame); TGCompositeFrame *t2cf2 = new TGCompositeFrame(tab2, 60, 20, kHorizontalFrame); TGCompositeFrame *t2cf3 = new TGCompositeFrame(tab2, 60, 20, kHorizontalFrame); TGCompositeFrame *gff = new TGCompositeFrame(tab2, 60, 20, kHorizontalFrame); TGGroupFrame *t2gf1 = new TGGroupFrame(gff, new TGString("Other Drawing Options: ")); TGLabel *linecolor = new TGLabel(t2cf1, new TGString("1st Line Color: ")); TGLabel *fillcolor = new TGLabel(t2cf1, new TGString("1st Fill Color: ")); TGLabel *l2ndcolor = new TGLabel(t2cf2, new TGString("2nd Line Color: ")); TGLabel *f2ndcolor = new TGLabel(t2cf2, new TGString("2nd Fill Color: ")); TGLabel *mktypes = new TGLabel(t2cf3, new TGString("Marker Style: ")); TGLabel *errtype = new TGLabel(t2cf3, new TGString("Error Bars: ")); fDrawOpts[0] = new TGCheckButton(t2gf1, "Bar Graph", 20); fDrawOpts[1] = new TGCheckButton(t2gf1, "Smooth Curve Plot", 21); fDrawOpts[2] = new TGCheckButton(t2gf1, "Use Markers", 22); fDrawOpts[3] = new TGCheckButton(t2gf1, "Line Plot", 23); fDrawOpts[4] = new TGCheckButton(t2gf1, "Plot Lego Style", 24); f1stLine = new TGComboBox(t2cf1, 30); f1stFill = new TGComboBox(t2cf1, 31); f2ndLine = new TGComboBox(t2cf2, 32); f2ndFill = new TGComboBox(t2cf2, 33); fMarkers = new TGComboBox(t2cf3, 34); fErrorBars = new TGComboBox(t2cf3, 35); t2cf1->AddFrame(linecolor, labhint); t2cf1->AddFrame(f1stLine, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 7, 5, 0, 0)); t2cf1->AddFrame(fillcolor, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 5, 5, 0, 0)); t2cf1->AddFrame(f1stFill, new TGLayoutHints(kLHintsRight | kLHintsCenterY, 0, 5, 0, 0)); t2cf2->AddFrame(l2ndcolor, labhint); t2cf2->AddFrame(f2ndLine, labhint); t2cf2->AddFrame(f2ndcolor, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 4, 0, 0)); t2cf2->AddFrame(f2ndFill, new TGLayoutHints(kLHintsRight | kLHintsCenterY, 0, 5, 0, 0)); t2cf3->AddFrame(mktypes, labhint); t2cf3->AddFrame(fMarkers, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 14, 5, 0, 0)); t2cf3->AddFrame(errtype, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 22, 4, 0, 0)); t2cf3->AddFrame(fErrorBars, new TGLayoutHints(kLHintsRight | kLHintsCenterY, 0, 5, 0, 0)); t2gf1->AddFrame(fDrawOpts[0], labhint); t2gf1->AddFrame(fDrawOpts[1], labhint); t2gf1->AddFrame(fDrawOpts[2], labhint); t2gf1->AddFrame(fDrawOpts[3], labhint); t2gf1->AddFrame(fDrawOpts[4], labhint); f1stLine->Resize(100,20); f1stFill->Resize(100,20); f2ndLine->Resize(100,20); f2ndFill->Resize(100,20); fMarkers->Resize(100,20); fErrorBars->Resize(100,20); f1stLine->AddEntry("Black", 1); f1stLine->AddEntry("Red", 2); f1stLine->AddEntry("Green", 3); f1stLine->AddEntry("Blue", 4); f1stLine->AddEntry("Magenta", 5); f1stLine->AddEntry("Cyan", 6); f1stLine->Select(1); //Defines default color f1stFill->AddEntry("Black", 1); f1stFill->AddEntry("Red", 2); f1stFill->AddEntry("Green", 3); f1stFill->AddEntry("Blue", 4); f1stFill->AddEntry("Magenta", 5); f1stFill->AddEntry("Cyan", 6); f1stFill->Select(2); f2ndLine->AddEntry("Black", 1); f2ndLine->AddEntry("Red", 2); f2ndLine->AddEntry("Green", 3); f2ndLine->AddEntry("Blue", 4); f2ndLine->AddEntry("Magenta", 5); f2ndLine->AddEntry("Cyan", 6); f2ndLine->Select(4); f2ndFill->AddEntry("Black", 1); f2ndFill->AddEntry("Red", 2); f2ndFill->AddEntry("Green", 3); f2ndFill->AddEntry("Blue", 4); f2ndFill->AddEntry("Magenta", 5); f2ndFill->AddEntry("Cyan", 6); f2ndFill->Select(3); fMarkers->AddEntry("Circles", 1); fMarkers->AddEntry("Squares", 2); fMarkers->AddEntry("Crosses", 3); fMarkers->AddEntry("Diamonds", 4); fMarkers->AddEntry("Stars", 5); fMarkers->Select(1); fErrorBars->AddEntry("None", 1); fErrorBars->AddEntry("Type 1", 2); fErrorBars->AddEntry("Type 2", 3); fErrorBars->AddEntry("Type 3", 4); fErrorBars->AddEntry("Type 4", 5); fErrorBars->Select(1); fDrawOpts[0]->SetState(kButtonDown); fDrawOpts[2]->SetState(kButtonDown); // Sets default options fDrawOpts[0]->Associate(this); fDrawOpts[1]->Associate(this); fDrawOpts[2]->Associate(this); fDrawOpts[3]->Associate(this); fDrawOpts[4]->Associate(this); f1stLine->Associate(this); f1stFill->Associate(this); f2ndLine->Associate(this); f2ndFill->Associate(this); fMarkers->Associate(this); fErrorBars->Associate(this); fRadioFrame = new TGGroupFrame(gff, new TGString("Histogram Type: ")); fRadios[0] = new TGRadioButton(fRadioFrame, "Voltage", 80); fRadios[1] = new TGRadioButton(fRadioFrame, "Current", 81); fRadios[2] = new TGRadioButton(fRadioFrame, "Demand Voltage", 82); fRadios[3] = new TGRadioButton(fRadioFrame, "Voltage/Demand Voltage", 83); fRadioFrame->AddFrame(fRadios[0], fL1); fRadioFrame->AddFrame(fRadios[1], fL1); fRadioFrame->AddFrame(fRadios[2], fL1); fRadioFrame->AddFrame(fRadios[3], fL1); fRadios[0]->Associate(this); fRadios[1]->Associate(this); fRadios[2]->Associate(this); fRadios[3]->Associate(this); fRadios[0]->SetState(kButtonDown); //Default // Drawing options & histogram type gff->AddFrame(fRadioFrame, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 0, 5, 0, 0)); gff->AddFrame(t2gf1, new TGLayoutHints(kLHintsRight | kLHintsCenterY, 5, 0, 0, 0)); tab2->AddFrame(t2cf1, fL3); tab2->AddFrame(t2cf2, fL3); tab2->AddFrame(t2cf3, fL3); tab2->AddFrame(gff, fL3); tf->AddFrame(tab2, fL3); //TAB #3 tf = fTab->AddTab("Graph"); /// 5 labels, 5 combo boxes, 4 checkboxes, 5 radio buttons TGCompositeFrame *tab3 = new TGCompositeFrame(tf, 60, 20, kVerticalFrame); TGCompositeFrame *t3cf1 = new TGCompositeFrame(tab3, 60, 20, kHorizontalFrame); TGCompositeFrame *t3cf2 = new TGCompositeFrame(tab3, 60, 20, kHorizontalFrame); TGCompositeFrame *t3cf3 = new TGCompositeFrame(tab3, 60, 20, kHorizontalFrame); TGCompositeFrame *t3cf4 = new TGCompositeFrame(tab3, 60, 20, kHorizontalFrame); TGGroupFrame *t3gf1 = new TGGroupFrame(t3cf4, new TGString("Other Drawing Options: ")); TGGroupFrame *t3gf2 = new TGGroupFrame(t3cf4, new TGString("Graph Type: ")); TGLabel *glinelabel = new TGLabel(t3cf1, new TGString("Graph Line Color: ")); TGLabel *gfilllabel = new TGLabel(t3cf1, new TGString("Fill Color: ")); TGLabel *gl2ndcolor = new TGLabel(t3cf2, new TGString("Canvas BG Color: ")); TGLabel *gf2ndcolor = new TGLabel(t3cf2, new TGString("BG Color: ")); TGLabel *gmktypes = new TGLabel(t3cf3, new TGString("Marker Style: ")); fGrfOpts[0] = new TGCheckButton(t3gf1, "Bar Graph", 40); fGrfOpts[1] = new TGCheckButton(t3gf1, "Smooth Curve Plot", 41); fGrfOpts[2] = new TGCheckButton(t3gf1, "Use Markers", 42); fGrfOpts[3] = new TGCheckButton(t3gf1, "Line Plot", 43); fGrfLine = new TGComboBox(t3cf1, 50); fGrfFill = new TGComboBox(t3cf1, 51); fGrfCvs = new TGComboBox(t3cf2, 52); fGrfBG = new TGComboBox(t3cf2, 53); fGrfMark = new TGComboBox(t3cf3, 54); t3cf1->AddFrame(glinelabel, labhint); t3cf1->AddFrame(fGrfLine, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 5, 5, 0, 0)); t3cf1->AddFrame(gfilllabel, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 5, 5, 0, 0)); t3cf1->AddFrame(fGrfFill, new TGLayoutHints(kLHintsRight | kLHintsCenterY, 0, 5, 0, 0)); t3cf2->AddFrame(gl2ndcolor, labhint); t3cf2->AddFrame(fGrfCvs, labhint); t3cf2->AddFrame(gf2ndcolor, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 5, 5, 0, 0)); t3cf2->AddFrame(fGrfBG, new TGLayoutHints(kLHintsRight | kLHintsCenterY, 0, 5, 0, 0)); t3cf3->AddFrame(gmktypes, labhint); t3cf3->AddFrame(fGrfMark, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 29, 5, 0, 0)); t3gf1->AddFrame(fGrfOpts[0], labhint); t3gf1->AddFrame(fGrfOpts[1], labhint); t3gf1->AddFrame(fGrfOpts[2], labhint); t3gf1->AddFrame(fGrfOpts[3], labhint); fGrfLine->Resize(100,20); fGrfFill->Resize(100,20); fGrfCvs->Resize(100,20); fGrfBG->Resize(100,20); fGrfMark->Resize(100,20); fGrfLine->AddEntry("Black", 1); fGrfLine->AddEntry("Red", 2); fGrfLine->AddEntry("Green", 3); fGrfLine->AddEntry("Blue", 4); fGrfLine->AddEntry("Magenta", 5); fGrfLine->AddEntry("Cyan", 6); fGrfLine->Select(4); fGrfFill->AddEntry("Black", 1); fGrfFill->AddEntry("Red", 2); fGrfFill->AddEntry("Green", 3); fGrfFill->AddEntry("Blue", 4); fGrfFill->AddEntry("Magenta", 5); fGrfFill->AddEntry("Cyan", 6); fGrfFill->Select(2); fGrfCvs->AddEntry("Black", 1); fGrfCvs->AddEntry("Red", 2); fGrfCvs->AddEntry("Green", 3); fGrfCvs->AddEntry("Blue", 4); fGrfCvs->AddEntry("Magenta", 5); fGrfCvs->AddEntry("Cyan", 6); fGrfCvs->Select(6); fGrfBG->AddEntry("Black", 1); fGrfBG->AddEntry("Red", 2); fGrfBG->AddEntry("Green", 3); fGrfBG->AddEntry("Blue", 4); fGrfBG->AddEntry("Magenta", 5); fGrfBG->AddEntry("Cyan", 6); fGrfBG->Select(3); fGrfMark->AddEntry("Circles", 1); fGrfMark->AddEntry("Squares", 2); fGrfMark->AddEntry("Crosses", 3); fGrfMark->AddEntry("Diamonds", 4); fGrfMark->AddEntry("Stars", 5); fGrfMark->Select(1); fGrfOpts[2]->SetState(kButtonDown); fGrfOpts[1]->SetState(kButtonDown); // Sets Default Options fGrfOpts[0]->Associate(this); fGrfOpts[1]->Associate(this); fGrfOpts[2]->Associate(this); fGrfOpts[3]->Associate(this); fGrfLine->Associate(this); fGrfFill->Associate(this); fGrfCvs->Associate(this); fGrfBG->Associate(this); fGrfMark->Associate(this); fGrfRadios[0] = new TGRadioButton(t3gf2, "Voltage vs. Time", 90); fGrfRadios[1] = new TGRadioButton(t3gf2, "Current vs. Time", 91); fGrfRadios[2] = new TGRadioButton(t3gf2, "Demand Voltage vs. Time", 92); fGrfRadios[3] = new TGRadioButton(t3gf2, "Status vs. Time", 93); fGrfRadios[4] = new TGRadioButton(t3gf2, "Enable vs. Time", 94); t3gf2->AddFrame(fGrfRadios[0], fL1); t3gf2->AddFrame(fGrfRadios[1], fL1); t3gf2->AddFrame(fGrfRadios[2], fL1); t3gf2->AddFrame(fGrfRadios[3], fL1); t3gf2->AddFrame(fGrfRadios[4], fL1); fGrfRadios[0]->Associate(this); fGrfRadios[1]->Associate(this); fGrfRadios[2]->Associate(this); fGrfRadios[3]->Associate(this); fGrfRadios[4]->Associate(this); fGrfRadios[0]->SetState(kButtonDown); //Default t3cf4->AddFrame(t3gf2, new TGLayoutHints(kLHintsLeft | kLHintsTop, 0, 5, 0, 0)); t3cf4->AddFrame(t3gf1, new TGLayoutHints(kLHintsRight | kLHintsTop, 5, 0, 0, 0)); tab3->AddFrame(t3cf1, fL3); tab3->AddFrame(t3cf2, fL3); tab3->AddFrame(t3cf3, fL3); tab3->AddFrame(t3cf4, fL3); tf->AddFrame(tab3, fL3); //TAB #4 tf = fTab->AddTab("2D Histograms"); // 3 group frames, with 2 groups of radio buttons and 1 checkbox group TGCompositeFrame *tab4 = new TGCompositeFrame(tf, 60, 20, kVerticalFrame); TGCompositeFrame *top = new TGCompositeFrame(tab4, 60, 20, kHorizontalFrame); TGGroupFrame *t4gf1 = new TGGroupFrame(top, new TGString("Histogram Type: ")); TGGroupFrame *t4gf2 = new TGGroupFrame(top, new TGString("Other Options: ")); TGGroupFrame *t4gf3 = new TGGroupFrame(tab4, new TGString("Histogram Style: ")); TGCompositeFrame *t4cf1 = new TGCompositeFrame(t4gf1, 80, 20, kHorizontalFrame); f2DType[0] = new TGRadioButton(t4cf1, "V vs. C", 60); f2DType[1] = new TGRadioButton(t4cf1, "V vs. Time", 61); t4cf1->AddFrame(f2DType[0], new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 3, 19, 0, 0)); t4cf1->AddFrame(f2DType[1], new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 3, 0, 0, 0)); TGCompositeFrame *t4cf2 = new TGCompositeFrame(t4gf1, 80, 20, kHorizontalFrame); f2DType[2] = new TGRadioButton(t4cf2, "V vs. DV", 62); f2DType[3] = new TGRadioButton(t4cf2, "C vs. Time", 63); t4cf2->AddFrame(f2DType[2], new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 3, 10, 0, 0)); t4cf2->AddFrame(f2DType[3], new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 3, 0, 0, 0)); TGCompositeFrame *t4cf3 = new TGCompositeFrame(t4gf1, 80, 20, kHorizontalFrame); f2DType[4] = new TGRadioButton(t4cf3, "DV vs. C", 64); f2DType[5] = new TGRadioButton(t4cf3, "DV vs. Time", 65); t4cf3->AddFrame(f2DType[4], new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 3, 10, 0, 0)); t4cf3->AddFrame(f2DType[5], new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 3, 0, 0, 0)); t4gf1->AddFrame(t4cf1, fL1); t4gf1->AddFrame(t4cf2, fL1); t4gf1->AddFrame(t4cf3, fL1); for (int n=0; n<6; n++) f2DType[n]->Associate(this); f2DType[0]->SetState(kButtonDown); TGCompositeFrame *t4cf4 = new TGCompositeFrame(t4gf2, 60, 20, kVerticalFrame); f2DBoxOpts[0] = new TGCheckButton(t4cf4, "Conceal Front Box", 66); f2DBoxOpts[1] = new TGCheckButton(t4cf4, "Conceal Back Box", 67); t4cf4->AddFrame(f2DBoxOpts[0], labhint); t4cf4->AddFrame(f2DBoxOpts[1], labhint); f2DBoxOpts[0]->Associate(this); f2DBoxOpts[1]->Associate(this); t4gf2->AddFrame(t4cf4, fL1); TGCompositeFrame *t4cf5 = new TGCompositeFrame(t4gf3, 60, 20, kHorizontalFrame); TGCompositeFrame *t4cf6 = new TGCompositeFrame(t4gf3, 60, 20, kHorizontalFrame); TGCompositeFrame *t4cf7 = new TGCompositeFrame(t4gf3, 60, 20, kHorizontalFrame); TGCompositeFrame *t4cf8 = new TGCompositeFrame(t4gf3, 60, 20, kHorizontalFrame); TGCompositeFrame *t4cf9 = new TGCompositeFrame(t4gf3, 60, 20, kHorizontalFrame); f2DOpts[0] = new TGRadioButton(t4cf5, "Scatter", 110); f2DOpts[1] = new TGRadioButton(t4cf5, "Arrow", 111); f2DOpts[2] = new TGRadioButton(t4cf5, "Box", 112); f2DOpts[3] = new TGRadioButton(t4cf6, "Surface 1", 113); f2DOpts[4] = new TGRadioButton(t4cf6, "Surface 2", 114); f2DOpts[5] = new TGRadioButton(t4cf6, "Surface 3", 115); f2DOpts[6] = new TGRadioButton(t4cf7, "Surface 4", 116); f2DOpts[7] = new TGRadioButton(t4cf7, "Surface 5", 117); f2DOpts[8] = new TGRadioButton(t4cf7, "Color", 118); f2DOpts[9] = new TGRadioButton(t4cf8, "Lego 1", 119); f2DOpts[10] = new TGRadioButton(t4cf8, "Lego 2", 120); f2DOpts[11] = new TGRadioButton(t4cf8, "Lego 3", 121); f2DOpts[12] = new TGRadioButton(t4cf9, "Contour 1", 122); f2DOpts[13] = new TGRadioButton(t4cf9, "Contour 2", 123); f2DOpts[14] = new TGRadioButton(t4cf9, "Contour 3", 124); t4cf5->AddFrame(f2DOpts[0], new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 3, 0, 0, 0)); t4cf5->AddFrame(f2DOpts[1], new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 43, 0, 0, 0)); t4cf5->AddFrame(f2DOpts[2], new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 51, 0, 0, 0)); t4cf6->AddFrame(f2DOpts[3], new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 3, 0, 0, 0)); t4cf6->AddFrame(f2DOpts[4], new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 30, 0, 0, 0)); t4cf6->AddFrame(f2DOpts[5], new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 30, 0, 0, 0)); t4cf7->AddFrame(f2DOpts[6], new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 3, 0, 0, 0)); t4cf7->AddFrame(f2DOpts[7], new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 30, 0, 0, 0)); t4cf7->AddFrame(f2DOpts[8], new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 30, 0, 0, 0)); t4cf8->AddFrame(f2DOpts[9], new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 3, 0, 0, 0)); t4cf8->AddFrame(f2DOpts[10], new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 45, 0, 0, 0)); t4cf8->AddFrame(f2DOpts[11], new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 45, 0, 0, 0)); t4cf9->AddFrame(f2DOpts[12], new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 3, 0, 0, 0)); t4cf9->AddFrame(f2DOpts[13], new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 28, 0, 0, 0)); t4cf9->AddFrame(f2DOpts[14], new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 28, 0, 0, 0)); for(n=0; n<15; n++) f2DOpts[n]->Associate(this); t4gf3->AddFrame(t4cf5, fL1); t4gf3->AddFrame(t4cf6, fL1); t4gf3->AddFrame(t4cf7, fL1); t4gf3->AddFrame(t4cf8, fL1); t4gf3->AddFrame(t4cf9, fL1); f2DOpts[0]->SetState(kButtonDown); // Default top->AddFrame(t4gf1, new TGLayoutHints(kLHintsLeft | kLHintsTop, 0, 5, 0, 0)); top->AddFrame(t4gf2, new TGLayoutHints(kLHintsRight | kLHintsTop, 5, 0, 0, 0)); tab4->AddFrame(top, new TGLayoutHints(kLHintsLeft | kLHintsTop, 0, 0, 0, 0)); tab4->AddFrame(t4gf3, new TGLayoutHints(kLHintsLeft | kLHintsBottom, 0, 0, 0, 0)); tf->AddFrame(tab4, fL3); //TAB #5 tf = fTab->AddTab("Histogram Options"); //2 group frames, 7 labels, 7 textentry fields TGCompositeFrame *tab5 = new TGCompositeFrame(tf, 60, 20, kHorizontalFrame); TGGroupFrame *t5gf1 = new TGGroupFrame(tab5, new TGString("1D Range Options: ")); TGGroupFrame *t5gf2 = new TGGroupFrame(tab5, new TGString("2D Range Options: ")); TGCompositeFrame *t5cf1 = new TGCompositeFrame(t5gf1, 60, 20, kHorizontalFrame); TGCompositeFrame *t5cf2 = new TGCompositeFrame(t5gf1, 60, 20, kHorizontalFrame); TGCompositeFrame *t5cf3 = new TGCompositeFrame(t5gf1, 60, 20, kHorizontalFrame); TGLabel *binlab = new TGLabel(t5cf1, new TGString("# of Bins: ")); TGLabel *r1lab = new TGLabel(t5cf2, new TGString("Voltage Range: ")); TGLabel *r2lab = new TGLabel(t5cf3, new TGString("Current Range: ")); fNumBinText = new TGTextEntry(t5cf1, fNumBinbuf = new TGTextBuffer(50), 70); fRange1Text = new TGTextEntry(t5cf2, fRange1buf = new TGTextBuffer(50), 71); fRange2Text = new TGTextEntry(t5cf3, fRange2buf = new TGTextBuffer(50), 72); fNumBinText->Associate(this); fRange1Text->Associate(this); fRange2Text->Associate(this); fNumBinbuf->AddText(0,"100"); fRange1buf->AddText(0,"4.000"); fRange2buf->AddText(0,"80.000"); fNumBinText->Resize(60, fNumBinText->GetDefaultHeight()); fRange1Text->Resize(60, fRange1Text->GetDefaultHeight()); fRange2Text->Resize(60, fRange2Text->GetDefaultHeight()); t5cf1->AddFrame(binlab, labhint); t5cf1->AddFrame(fNumBinText, new TGLayoutHints(kLHintsRight | kLHintsCenterY, 5, 0, 0, 0)); t5cf2->AddFrame(r1lab, labhint); t5cf2->AddFrame(fRange1Text, new TGLayoutHints(kLHintsRight | kLHintsCenterY, 5, 0, 0, 0)); t5cf3->AddFrame(r2lab, labhint); t5cf3->AddFrame(fRange2Text, new TGLayoutHints(kLHintsRight | kLHintsCenterY, 5, 0, 0, 0)); t5gf1->AddFrame(t5cf1, fL1); t5gf1->AddFrame(t5cf2, fL1); t5gf1->AddFrame(t5cf3, fL1); TGCompositeFrame *t5cf4 = new TGCompositeFrame(t5gf2, 60, 20, kHorizontalFrame); TGCompositeFrame *t5cf5 = new TGCompositeFrame(t5gf2, 60, 20, kHorizontalFrame); TGCompositeFrame *t5cf6 = new TGCompositeFrame(t5gf2, 60, 20, kHorizontalFrame); TGCompositeFrame *t5cf7 = new TGCompositeFrame(t5gf2, 60, 20, kHorizontalFrame); TGLabel *xlab = new TGLabel(t5cf4, new TGString("X: # of Bins: ")); TGLabel *ylab = new TGLabel(t5cf5, new TGString("Y: # of Bins: ")); TGLabel *voltlab = new TGLabel(t5cf6, new TGString("Voltage Range: ")); TGLabel *currlab = new TGLabel(t5cf7, new TGString("Current Range: ")); f2DXBinText = new TGTextEntry(t5cf4, f2DXBinbuf = new TGTextBuffer(50), 73); f2DYBinText = new TGTextEntry(t5cf5, f2DYBinbuf = new TGTextBuffer(50), 74); f2DVoltRangeText = new TGTextEntry(t5cf6, f2DVoltRangebuf = new TGTextBuffer(50), 75); f2DCurrRangeText = new TGTextEntry(t5cf7, f2DCurrRangebuf = new TGTextBuffer(50), 76); f2DXBinText->Associate(this); f2DYBinText->Associate(this); f2DVoltRangeText->Associate(this); f2DCurrRangeText->Associate(this); f2DXBinbuf->AddText(0, "30"); f2DYBinbuf->AddText(0, "30"); f2DVoltRangebuf->AddText(0, "3.000"); f2DCurrRangebuf->AddText(0, "50.000"); f2DXBinText->Resize(60, f2DXBinText->GetDefaultHeight()); f2DYBinText->Resize(60, f2DYBinText->GetDefaultHeight()); f2DVoltRangeText->Resize(60, f2DVoltRangeText->GetDefaultHeight()); f2DCurrRangeText->Resize(60, f2DCurrRangeText->GetDefaultHeight()); t5cf4->AddFrame(xlab, labhint); t5cf4->AddFrame(f2DXBinText, new TGLayoutHints(kLHintsRight | kLHintsCenterY, 5, 0, 0, 0)); t5cf5->AddFrame(ylab, labhint); t5cf5->AddFrame(f2DYBinText, new TGLayoutHints(kLHintsRight | kLHintsCenterY, 5, 0, 0, 0)); t5cf6->AddFrame(voltlab, labhint); t5cf6->AddFrame(f2DVoltRangeText, new TGLayoutHints(kLHintsRight | kLHintsCenterY, 5, 0, 0, 0)); t5cf7->AddFrame(currlab, labhint); t5cf7->AddFrame(f2DCurrRangeText, new TGLayoutHints(kLHintsRight | kLHintsCenterY, 5, 0, 0, 0)); t5gf2->AddFrame(t5cf4, fL1); t5gf2->AddFrame(t5cf5, fL1); t5gf2->AddFrame(t5cf6, fL1); t5gf2->AddFrame(t5cf7, fL1); tab5->AddFrame(t5gf1, fL1); tab5->AddFrame(t5gf2, new TGLayoutHints(kLHintsRight | kLHintsCenterY, 5, 0, 0, 0)); tf->AddFrame(tab5, fL3); AddFrame(fTab, new TGLayoutHints(kLHintsBottom | kLHintsExpandX | kLHintsExpandY, 2, 2, 5, 1)); numchannels = -1; numPads = 1; strcpy(configFileName, ""); Bool_t cfnamefound = kFALSE; if (argc>1) { //get configuration file name from command line argument for (i=0; iGetString(), "DEMO")==0 && !cfnamefound) { if (OpenConfigFile(1, "DEMO.DPC")!=1) { cout << "Command Line Argument Error: DEMO.DPC Not Found" << endl; } else { cout << "INITIAL CONFIG FILE = DEMO.DPC" << endl << endl; cfnamefound = kTRUE; } } if (!cfnamefound) cout << "INITIAL CONFIG FILE = NONE -- USING DEFAULT CONFIGURATION" << endl << endl; // The DEMO database uses large voltage/current ranges in it's histograms, // so I've made a separate Configuration for it. // Fill Drawing Variables fCHList = new TSortedList(); changedDB = kTRUE; for( int s = 0; sSetState(kButtonUp); if (status==-2) { new TGMsgBox(fClient->GetRoot(), this, "Error in DB Function!", "Database Access Error -- Plotting Stopped.", kMBIconStop, kMBOk, &retval); } else if (status!=1) { // ERROR -- Create Message Window new TGMsgBox(fClient->GetRoot(), this, "Error in Plotting!", "Indeterminate Plot Option -- Plotting Stopped.", kMBIconStop, kMBOk, &retval); } }; HVDPMainFrame::~HVDPMainFrame() { //Destructor gets rid of widgets for (int i=0; iTerminate(0); } int HVDPMainFrame::HandleCombo(Long_t parm1, Long_t parm2) { // parm1 is the widget id number, parm2 is the id of the widget selction Int_t pad2config; pad2config = fPadBox->GetSelected(); switch (parm1) { case 30: switch (parm2) { case 1: fMyConfig->SetLine1(pad2config, kBlack); break; case 2: fMyConfig->SetLine1(pad2config, kRed); break; case 3: fMyConfig->SetLine1(pad2config, kGreen); break; case 4: fMyConfig->SetLine1(pad2config, kBlue); break; case 5: fMyConfig->SetLine1(pad2config, kMagenta); break; case 6: fMyConfig->SetLine1(pad2config, kCyan); break; } break; case 31: switch (parm2) { case 1: fMyConfig->SetFill1(pad2config, kBlack); break; case 2: fMyConfig->SetFill1(pad2config, kRed); break; case 3: fMyConfig->SetFill1(pad2config, kGreen); break; case 4: fMyConfig->SetFill1(pad2config, kBlue); break; case 5: fMyConfig->SetFill1(pad2config, kMagenta); break; case 6: fMyConfig->SetFill1(pad2config, kCyan); break; } break; case 32: switch (parm2) { case 1: fMyConfig->SetLine2(pad2config, kBlack); break; case 2: fMyConfig->SetLine2(pad2config, kRed); break; case 3: fMyConfig->SetLine2(pad2config, kGreen); break; case 4: fMyConfig->SetLine2(pad2config, kBlue); break; case 5: fMyConfig->SetLine2(pad2config, kMagenta); break; case 6: fMyConfig->SetLine2(pad2config, kCyan); break; } break; case 33: switch (parm2) { case 1: fMyConfig->SetFill2(pad2config, kBlack); break; case 2: fMyConfig->SetFill2(pad2config, kRed); break; case 3: fMyConfig->SetFill2(pad2config, kGreen); break; case 4: fMyConfig->SetFill2(pad2config, kBlue); break; case 5: fMyConfig->SetFill2(pad2config, kMagenta); break; case 6: fMyConfig->SetFill2(pad2config, kCyan); break; } break; case 34: switch (parm2) { case 1: fMyConfig->SetMarker(pad2config, 8); break; case 2: fMyConfig->SetMarker(pad2config, 21); break; case 3: fMyConfig->SetMarker(pad2config, 28); break; case 4: fMyConfig->SetMarker(pad2config, 27); break; case 5: fMyConfig->SetMarker(pad2config, 29); break; } break; case 35: fMyConfig->SetErrorBars(pad2config, parm2); break; case 50: switch (parm2) { case 1: fMyConfig->SetGraphLine(pad2config, kBlack); break; case 2: fMyConfig->SetGraphLine(pad2config, kRed); break; case 3: fMyConfig->SetGraphLine(pad2config, kGreen); break; case 4: fMyConfig->SetGraphLine(pad2config, kBlue); break; case 5: fMyConfig->SetGraphLine(pad2config, kMagenta); break; case 6: fMyConfig->SetGraphLine(pad2config, kCyan); break; } break; case 51: switch (parm2) { case 1: fMyConfig->SetGraphFill(pad2config, kBlack); break; case 2: fMyConfig->SetGraphFill(pad2config, kRed); break; case 3: fMyConfig->SetGraphFill(pad2config, kGreen); break; case 4: fMyConfig->SetGraphFill(pad2config, kBlue); break; case 5: fMyConfig->SetGraphFill(pad2config, kMagenta); break; case 6: fMyConfig->SetGraphFill(pad2config, kCyan); break; } break; case 52: switch (parm2) { case 1: fMyConfig->SetGraphCanvas(pad2config, kBlack); break; case 2: fMyConfig->SetGraphCanvas(pad2config, kRed); break; case 3: fMyConfig->SetGraphCanvas(pad2config, kGreen); break; case 4: fMyConfig->SetGraphCanvas(pad2config, kBlue); break; case 5: fMyConfig->SetGraphCanvas(pad2config, kMagenta); break; case 6: fMyConfig->SetGraphCanvas(pad2config, kCyan); break; } break; case 53: switch (parm2) { case 1: fMyConfig->SetGraphBG(pad2config, kBlack); break; case 2: fMyConfig->SetGraphBG(pad2config, kRed); break; case 3: fMyConfig->SetGraphBG(pad2config, kGreen); break; case 4: fMyConfig->SetGraphBG(pad2config, kBlue); break; case 5: fMyConfig->SetGraphBG(pad2config, kMagenta); break; case 6: fMyConfig->SetGraphBG(pad2config, kCyan); break; } break; case 54: switch (parm2) { case 1: fMyConfig->SetGraphMarker(pad2config, 8); break; case 2: fMyConfig->SetGraphMarker(pad2config, 21); break; case 3: fMyConfig->SetGraphMarker(pad2config, 28); break; case 4: fMyConfig->SetGraphMarker(pad2config, 27); break; case 5: fMyConfig->SetGraphMarker(pad2config, 29); break; } break; case 301: fMyConfig->SetPlotKind(pad2config, parm2); break; default: break; } return 1; } int HVDPMainFrame::HandleRadio(Long_t parm1) { Int_t pad2config; pad2config = fPadBox->GetSelected(); // parm1 is the widget id number switch (parm1) { case 80: case 81: case 82: case 83: fMyConfig->SetType1D(pad2config, parm1-80); break; case 90: case 91: case 92: case 93: case 94: fMyConfig->SetTypeGraph(pad2config, parm1-90); break; case 60: case 61: case 62: case 63: case 64: case 65: fMyConfig->SetType2D(pad2config, parm1-60); break; case 110: case 111: case 112: case 113: case 114: case 115: case 116: case 117: case 118: case 119: case 120: case 121: case 122: case 123: case 124: fMyConfig->SetPlotSubType(pad2config, parm1-110); break; default: break; } return 1; } int HVDPMainFrame::HandleCheck(Long_t parm1) { // parm1 is the widget id number Int_t pad2config; pad2config = fPadBox->GetSelected(); Int_t options; switch (parm1) { case 20: options = fMyConfig->GetPlot1DOptions(pad2config); if (fDrawOpts[0]->GetState() == kButtonUp) { options = ( options & 0xFFFE ); fMyConfig->SetPlot1DOptions(pad2config, options); } else { options = ( options | 0x0001 ); fMyConfig->SetPlot1DOptions(pad2config, options); } break; case 21: options = fMyConfig->GetPlot1DOptions(pad2config); if (fDrawOpts[1]->GetState() == kButtonUp) { options = ( options & 0xFFFD ); fMyConfig->SetPlot1DOptions(pad2config, options); } else { options = ( options | 0x0002 ); fMyConfig->SetPlot1DOptions(pad2config, options); } break; case 22: options = fMyConfig->GetPlot1DOptions(pad2config); if (fDrawOpts[2]->GetState() == kButtonUp) { options = ( options & 0xFFFB ); fMyConfig->SetPlot1DOptions(pad2config, options); } else { options = ( options | 0x0004 ); fMyConfig->SetPlot1DOptions(pad2config, options); } break; case 23: options = fMyConfig->GetPlot1DOptions(pad2config); if (fDrawOpts[3]->GetState() == kButtonUp) { options = ( options & 0xFFF7 ); fMyConfig->SetPlot1DOptions(pad2config, options); } else { options = ( options | 0x0008 ); fMyConfig->SetPlot1DOptions(pad2config, options); } break; case 24: options = fMyConfig->GetPlot1DOptions(pad2config); if (fDrawOpts[4]->GetState() == kButtonUp) { options = ( options & 0xFFEF ); fMyConfig->SetPlot1DOptions(pad2config, options); } else { options = ( options | 0x0010 ); fMyConfig->SetPlot1DOptions(pad2config, options); } break; case 40: options = fMyConfig->GetPlotGrfOptions(pad2config); if (fGrfOpts[0]->GetState() == kButtonUp) { options = ( options & 0xFFFE ); fMyConfig->SetPlotGrfOptions(pad2config, options); } else { options = ( options | 0x0001 ); fMyConfig->SetPlotGrfOptions(pad2config, options); } break; case 41: options = fMyConfig->GetPlotGrfOptions(pad2config); if (fGrfOpts[1]->GetState() == kButtonUp) { options = ( options & 0xFFFD ); fMyConfig->SetPlotGrfOptions(pad2config, options); } else { options = ( options | 0x0002 ); fMyConfig->SetPlotGrfOptions(pad2config, options); } break; case 42: options = fMyConfig->GetPlotGrfOptions(pad2config); if (fGrfOpts[2]->GetState() == kButtonUp) { options = ( options & 0xFFFB ); fMyConfig->SetPlotGrfOptions(pad2config, options); } else { options = ( options | 0x0004 ); fMyConfig->SetPlotGrfOptions(pad2config, options); } break; case 43: options = fMyConfig->GetPlotGrfOptions(pad2config); if (fGrfOpts[3]->GetState() == kButtonUp) { options = ( options & 0xFFF7 ); fMyConfig->SetPlotGrfOptions(pad2config, options); } else { options = ( options | 0x0008 ); fMyConfig->SetPlotGrfOptions(pad2config, options); } break; case 66: options = fMyConfig->GetPlot2DOptions(pad2config); if (f2DBoxOpts[0]->GetState() == kButtonUp) { options = ( options & 0xFFFE ); fMyConfig->SetPlot2DOptions(pad2config, options); } else { options = ( options | 0x0001 ); fMyConfig->SetPlot2DOptions(pad2config, options); } break; case 67: options = fMyConfig->GetPlot2DOptions(pad2config); if (f2DBoxOpts[1]->GetState() == kButtonUp) { options = ( options & 0xFFFD ); fMyConfig->SetPlot2DOptions(pad2config, options); } else { options = ( options | 0x0002 ); fMyConfig->SetPlot2DOptions(pad2config, options); } break; default: break; } return 1; } int HVDPMainFrame::HandleText(Long_t parm1) { // parm1 is the widget id number Int_t pad2config; pad2config = fPadBox->GetSelected(); int temp, retval; double temp2; switch (parm1) { case 70: temp = atoi( fNumBinbuf->GetString()); if (temp < 0) { fMyConfig->SetNum1DBins(pad2config, 100); fNumBinbuf->Clear(); fNumBinbuf->AddText(0, "100"); fClient->NeedRedraw(fNumBinText); new TGMsgBox(fClient->GetRoot(), this, "Error in Plotting!", "Invalid Number of 1D Histogram Bins -- Resetting to default (100)", kMBIconStop, kMBOk, &retval); } else fMyConfig->SetNum1DBins(pad2config, temp); break; case 71: temp2 = (double)atof( fRange1buf->GetString()); if ( temp2 < 0.0 ) { fMyConfig->SetVolt1D(pad2config, 5.0); fRange1buf->Clear(); fRange1buf->AddText(0, "5.0"); fClient->NeedRedraw(fRange1Text); new TGMsgBox(fClient->GetRoot(), this, "Error in Plotting!", "Invalid 1D Voltage Range -- Resetting to default (5.0)", kMBIconStop, kMBOk, &retval); } else fMyConfig->SetVolt1D(pad2config, temp2); break; case 72: temp2 = (double)atof( fRange2buf->GetString()); if ( temp2 < 0.0 ) { fMyConfig->SetCurr1D(pad2config, 100.0); fRange2buf->Clear(); fRange2buf->AddText(0, "100.0"); fClient->NeedRedraw(fRange2Text); new TGMsgBox(fClient->GetRoot(), this, "Error in Plotting!", "Invalid 1D Current Range -- Resetting to default (100.0)", kMBIconStop, kMBOk, &retval); } else fMyConfig->SetCurr1D(pad2config, temp2); break; case 73: temp = atoi( f2DXBinbuf->GetString()); if (temp < 0) { fMyConfig->SetNum2DXBins(pad2config, 30); f2DXBinbuf->Clear(); f2DXBinbuf->AddText(0, "30"); fClient->NeedRedraw(f2DXBinText); new TGMsgBox(fClient->GetRoot(), this, "Error in Plotting!", "Invalid Number of Histogram Bins (X axis) -- Resetting to default (30)", kMBIconStop, kMBOk, &retval); } else fMyConfig->SetNum2DXBins(pad2config, temp); break; case 74: temp = atoi( f2DYBinbuf->GetString()); if (temp < 0) { fMyConfig->SetNum2DYBins(pad2config, 30); f2DYBinbuf->Clear(); f2DYBinbuf->AddText(0, "30"); fClient->NeedRedraw(f2DYBinText); new TGMsgBox(fClient->GetRoot(), this, "Error in Plotting!", "Invalid Number of Histogram Bins (Y axis) -- Resetting to default (30)", kMBIconStop, kMBOk, &retval); } else fMyConfig->SetNum2DYBins(pad2config, temp); break; case 75: temp2 = (double)atof( f2DVoltRangebuf->GetString()); if ( temp2 < 0.0 ) { fMyConfig->SetVolt2D(pad2config, 3.0); f2DVoltRangebuf->Clear(); f2DVoltRangebuf->AddText(0, "3.0"); fClient->NeedRedraw(f2DVoltRangeText); new TGMsgBox(fClient->GetRoot(), this, "Error in Plotting!", "Invalid 2D Voltage Range -- Resetting to default (3.0)", kMBIconStop, kMBOk, &retval); } else fMyConfig->SetVolt2D(pad2config, temp2); break; case 76: temp2 = (double)atof( f2DCurrRangebuf->GetString()); if ( temp2 < 0.0 ) { fMyConfig->SetCurr2D(pad2config, 50.0); f2DCurrRangebuf->Clear(); f2DCurrRangebuf->AddText(0, "50.0"); fClient->NeedRedraw(f2DCurrRangeText); new TGMsgBox(fClient->GetRoot(), this, "Error in Plotting!", "Invalid 2D Current Range -- Resetting to default (50.0)", kMBIconStop, kMBOk, &retval); } else fMyConfig->SetCurr2D(pad2config, temp2); break; default: break; } return 1; } int HVDPMainFrame::Color2Index( Color_t col ) { int temp; if (col == kCyan ) temp = 6; else if (col == kMagenta ) temp = 5; else if (col == kBlue ) temp = 4; else if (col == kGreen ) temp = 3; else if (col == kRed ) temp = 2; else temp = 1; return temp; } int HVDPMainFrame::LoadConfiguration( int i ) { // Change Combo Box entries to match this pad's config fPlotKindBox->Select( fMyConfig->GetPlotKind(i) ); f1stLine->Select( Color2Index( fMyConfig->GetLine1(i) ) ); f1stFill->Select( Color2Index( fMyConfig->GetFill1(i) ) ); f2ndLine->Select( Color2Index( fMyConfig->GetLine2(i) ) ); f2ndFill->Select( Color2Index( fMyConfig->GetFill2(i) ) ); fErrorBars->Select( fMyConfig->GetErrorBars(i) ); fGrfLine->Select( Color2Index( fMyConfig->GetGraphLine(i) ) ); fGrfFill->Select( Color2Index( fMyConfig->GetGraphFill(i) ) ); fGrfCvs->Select( Color2Index( fMyConfig->GetGraphCanvas(i) ) ); fGrfBG->Select( Color2Index( fMyConfig->GetGraphBG(i) ) ); switch (fMyConfig->GetMarker1D(i)) { case 8: fMarkers->Select(1); break; case 21: fMarkers->Select(2); break; case 28: fMarkers->Select(3); break; case 27: fMarkers->Select(4); break; case 29: fMarkers->Select(5); break; } switch (fMyConfig->GetGraphMarker(i)) { case 8: fGrfMark->Select(1); break; case 21: fGrfMark->Select(2); break; case 28: fGrfMark->Select(3); break; case 27: fGrfMark->Select(4); break; case 29: fGrfMark->Select(5); break; } // Change Radio Button entries to match this pad's config int j, id; id = fMyConfig->GetType1D(i); for (j=0; j<4; j++) fRadios[j]->SetState(kButtonUp); fRadios[id]->SetState(kButtonDown); id = fMyConfig->GetTypeGraph(i); for (j=0; j<5; j++) fGrfRadios[j]->SetState(kButtonUp); fGrfRadios[id]->SetState(kButtonDown); id = fMyConfig->GetType2D(i); for (j=0; j<6; j++) f2DType[j]->SetState(kButtonUp); f2DType[id]->SetState(kButtonDown); id = fMyConfig->GetPlotSubType(i); for (j=0; j<15; j++) f2DOpts[j]->SetState(kButtonUp); f2DOpts[id]->SetState(kButtonDown); // Change Check Button entries to match this pad's config for (j=0; j<5; j++) fDrawOpts[j]->SetState(kButtonUp); id = fMyConfig->GetPlot1DOptions(i); if ( (id & 0x0001) == 1) { fDrawOpts[0]->SetState(kButtonDown); } if ( (id & 0x0002) == 2) { fDrawOpts[1]->SetState(kButtonDown); } if ( (id & 0x0004) == 4) { fDrawOpts[2]->SetState(kButtonDown); } if ( (id & 0x0008) == 8) { fDrawOpts[3]->SetState(kButtonDown); } if ( (id & 0x0010) == 16) { fDrawOpts[4]->SetState(kButtonDown); } for (j=0; j<4; j++) fGrfOpts[j]->SetState(kButtonUp); id = fMyConfig->GetPlotGrfOptions(i); if ( (id & 0x0001) == 1) fGrfOpts[0]->SetState(kButtonDown); if ( (id & 0x0002) == 2) fGrfOpts[1]->SetState(kButtonDown); if ( (id & 0x0004) == 4) fGrfOpts[2]->SetState(kButtonDown); if ( (id & 0x0008) == 8) fGrfOpts[3]->SetState(kButtonDown); for (j=0; j<2; j++) f2DBoxOpts[j]->SetState(kButtonUp); id = fMyConfig->GetPlot2DOptions(i); if ( (id & 0x0001) == 1) f2DBoxOpts[0]->SetState(kButtonDown); if ( (id & 0x0002) == 2) f2DBoxOpts[1]->SetState(kButtonDown); // Change Text Fields to match this pad's config int bins; double range; char text[25]; bins = fMyConfig->GetNum1DBins(i); fNumBinbuf->Clear(); sprintf(text, "%d", bins); fNumBinbuf->AddText(0, text); bins = fMyConfig->GetNum2DXBins(i); f2DXBinbuf->Clear(); sprintf(text, "%d", bins); f2DXBinbuf->AddText(0, text); bins = fMyConfig->GetNum2DYBins(i); f2DYBinbuf->Clear(); sprintf(text, "%d", bins); f2DYBinbuf->AddText(0, text); range = fMyConfig->GetVolt1D(i); fRange1buf->Clear(); sprintf(text, "%4.3lf", range); fRange1buf->AddText(0, text); range = fMyConfig->GetCurr1D(i); fRange2buf->Clear(); sprintf(text, "%4.3lf", range); fRange2buf->AddText(0, text); range = fMyConfig->GetVolt2D(i); f2DVoltRangebuf->Clear(); sprintf(text, "%4.3lf", range); f2DVoltRangebuf->AddText(0, text); range = fMyConfig->GetCurr2D(i); f2DCurrRangebuf->Clear(); sprintf(text, "%4.3lf", range); f2DCurrRangebuf->AddText(0, text); if ( fTab->GetCurrent() == 4 ) { //i.e., if currently on the // Histogram options tab fClient->NeedRedraw(fNumBinText); fClient->NeedRedraw(fRange1Text); fClient->NeedRedraw(fRange2Text); fClient->NeedRedraw(f2DXBinText); fClient->NeedRedraw(f2DYBinText); fClient->NeedRedraw(f2DVoltRangeText); fClient->NeedRedraw(f2DCurrRangeText); } return 1; } int HVDPMainFrame::SaveConfigFile() { TGFileInfo fi; fi.fFileTypes = (char **)filetypes; new TGFileDialog(fClient->GetRoot(), this, kFDSave, &fi); if (fi.fFilename == 0) return 1; // User hit 'Cancel' //cout << "You saved to the file " << fi.fFilename << ".DPC" << endl; //cout << "\tIn the Directory = " << gSystem->WorkingDirectory() << endl; Int_t pk, t1, tg, t2, pst, p1o, pgo, p2o; Color_t l1, f1, l2, f2, gl, gf, gc, gbg; Int_t m1, mg, eb, b1, bx, by; Float_t v1, c1, v2, c2; strcpy(configFileName, fi.fFilename); strcat(configFileName, ".DPC"); ofstream outFile( configFileName, ios::out ); for (int i=0; iGetPlotKind(i); t1 = fMyConfig->GetType1D(i); tg = fMyConfig->GetTypeGraph(i); t2 = fMyConfig->GetType2D(i); pst = fMyConfig->GetPlotSubType(i); p1o = fMyConfig->GetPlot1DOptions(i); pgo = fMyConfig->GetPlotGrfOptions(i); p2o = fMyConfig->GetPlot2DOptions(i); l1 = fMyConfig->GetLine1(i); f1 = fMyConfig->GetFill1(i); l2 = fMyConfig->GetLine2(i); f2 = fMyConfig->GetFill2(i); m1 = fMyConfig->GetMarker1D(i); gl = fMyConfig->GetGraphLine(i); gf = fMyConfig->GetGraphFill(i); gc = fMyConfig->GetGraphCanvas(i); gbg = fMyConfig->GetGraphBG(i); mg = fMyConfig->GetGraphMarker(i); eb = fMyConfig->GetErrorBars(i); b1 = fMyConfig->GetNum1DBins(i); bx = fMyConfig->GetNum2DXBins(i); by = fMyConfig->GetNum2DYBins(i); v1 = fMyConfig->GetVolt1D(i); c1 = fMyConfig->GetCurr1D(i); v2 = fMyConfig->GetVolt2D(i); c2 = fMyConfig->GetCurr2D(i); outFile << "PAD " << i << endl; outFile << pk << " " << t1 << " " << tg << " " << t2 << " " << pst << " " << p1o << " " << pgo << " " << p2o << " " << l1 << " " << f1 << endl; outFile << l2 << " " << f2 << " " << m1 << " " << gl << " " << gf << " " << gc << " " << gbg << " " << mg << " " << eb << " " << b1 << endl; outFile << bx << " " << by << " " << v1 << " " << c1 << " " << v2 << " " << c2 << endl; } return 1; } int HVDPMainFrame::OpenConfigFile(int mode, char *filename) { if (mode==0) { TGFileInfo fi; fi.fFileTypes = (char **)filetypes; new TGFileDialog(fClient->GetRoot(), this, kFDOpen,&fi); //cout << "You selected the file " << fi.fFilename << endl; //cout << "\tIn the Directory = " << gSystem->WorkingDirectory() << endl; if (fi.fFilename == 0) return 1; //User hit 'Cancel' if (strstr(fi.fFilename, ".DPC")==NULL) { // NOT A CONFIGURATION FILE return -3; } strcpy(configFileName, fi.fFilename); } else strcpy(configFileName, filename); Int_t pk, t1, tg, t2, pst, p1o, pgo, p2o; Color_t l1, f1, l2, f2, gl, gf, gc, gbg; Int_t m1, mg, eb, b1, bx, by; Float_t v1, c1, v2, c2; char buf[20]; int padnum; ifstream inpFile( configFileName, ios::in ); if (!inpFile) { //i.e., file does not exist return -4; } for( int i=0; i> setw(20) >> buf >> padnum; //cout << buf << " " << padnum << " being recalled" << endl; inpFile >> pk >> t1 >> tg >> t2 >> pst >> p1o >> pgo >> p2o >> l1 >> f1; inpFile >> l2 >> f2 >> m1 >> gl >> gf >> gc >> gbg >> mg >> eb >> b1; inpFile >> bx >> by >> v1 >> c1 >> v2 >> c2; fMyConfig->SetPlotKind(i, pk); fMyConfig->SetType1D(i, t1); fMyConfig->SetTypeGraph(i, tg); fMyConfig->SetType2D(i, t2); fMyConfig->SetPlotSubType(i, pst); fMyConfig->SetPlot1DOptions(i, p1o); fMyConfig->SetPlotGrfOptions(i, pgo); fMyConfig->SetPlot2DOptions(i, p2o); fMyConfig->SetLine1(i, l1); fMyConfig->SetFill1(i, f1); fMyConfig->SetLine2(i, l2); fMyConfig->SetFill2(i, f2); fMyConfig->SetMarker(i, m1); fMyConfig->SetGraphLine(i, gl); fMyConfig->SetGraphFill(i, gf); fMyConfig->SetGraphCanvas(i, gc); fMyConfig->SetGraphBG(i, gbg); fMyConfig->SetGraphMarker(i, mg); fMyConfig->SetErrorBars(i, eb); fMyConfig->SetNum1DBins(i, b1); fMyConfig->SetNum2DXBins(i, bx); fMyConfig->SetNum2DYBins(i, by); fMyConfig->SetVolt1D(i, v1); fMyConfig->SetCurr1D(i, c1); fMyConfig->SetVolt2D(i, v2); fMyConfig->SetCurr2D(i, c2); } fPadBox->Select(0); LoadConfiguration(0); return 1; } int HVDPMainFrame::MaximizePad(Int_t padindex) { int status = 1; char canvastitle[32]; char title2[32]; sprintf(canvastitle, "ExpandedPadNumber%d", padindex+1); sprintf(title2, "Expanded Pad Number %d", padindex+1); if ((gROOT->GetListOfCanvases()->FindObject(canvastitle)==0) || (fMaxedPads[padindex]==NULL)) { fMaxedPads[padindex] = new TCanvas(canvastitle, title2, 200, 5, 900, 900); } Char_t options[20]; //cout << "Maximize Pad Number " << padindex+1 << " Name: " << chname << endl; switch (fMyConfig->GetPlotKind(padindex)) { case 1: Get1DOpts(options, padindex); if (fMyConfig->GetType1D(padindex)!=3 || (strstr(options, "lego2")!=NULL) ) { fMaxedPads[padindex]->cd(); fMaxedPads[padindex]->Clear(); fMaxedPads[padindex]->SetGrid(); fMaxedPads[padindex]->SetFillColor(21); fHisto[padindex]->SetMarkerSize(1); fHisto[padindex]->Draw(options); fMaxedPads[padindex]->Update(); } else { //Overlay Demand Voltage histogram on top of Voltage histogram (non-lego plot) fMaxedPads[padindex]->cd(); fMaxedPads[padindex]->Clear(); fMaxedPads[padindex]->SetGrid(); fMaxedPads[padindex]->SetFillColor(21); fHisto[padindex]->SetMarkerSize(1); fHisto[padindex]->Draw(options); char ctemp[20]; strcpy(ctemp, options); strcat(ctemp, "same"); fHisto2[padindex]->SetMarkerSize(1); fHisto2[padindex]->Draw(ctemp); fMaxedPads[padindex]->Update(); } break; case 2: GetGrfOpts(options, padindex); fMaxedPads[padindex]->cd(); fMaxedPads[padindex]->Clear(); fMaxedPads[padindex]->SetGrid(); fMaxedPads[padindex]->SetFillColor(fMyConfig->GetGraphCanvas(padindex)); ftf = fMaxedPads[padindex]->GetFrame(); ftf->SetFillColor(fMyConfig->GetGraphBG(padindex)); fHVGraph[padindex]->SetMarkerSize(1); fHVGraph[padindex]->Draw(options); fMaxedPads[padindex]->Update(); fholder = fHVGraph[padindex]->GetHistogram(); fholder->SetXTitle("Time (minutes)"); fMaxedPads[padindex]->Update(); break; case 3: Get2DOpts(options, padindex); fMaxedPads[padindex]->cd(); fMaxedPads[padindex]->Clear(); fMaxedPads[padindex]->SetGrid(); fMaxedPads[padindex]->SetFillColor(21); f2DHisto[padindex]->Draw(options); fMaxedPads[padindex]->Update(); break; } return status; } Bool_t HVDPMainFrame::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2) { //Function that defines what to do when window widgets are activated int status = 1; int i; // BELOW IS A USEFUL DEBUGGING STATMENT WHEN WIDGETS DON'T WORK CORRECTLY // MOST COMMON ERROR -- failing to call 'Associate(this)' for that widget /*cout << "Msg = " << msg << " GET_MSG = " << GET_MSG(msg) * << " SUB_MSG = " << GET_SUBMSG(msg) << " parm1 = " * << parm1 << " parm2 = " << parm2 << endl; */ switch (GET_MSG(msg)) { case kC_COMMAND: //command type event switch (GET_SUBMSG(msg)) { case kCM_MENU: switch (parm1) { case M_FILE_OPEN: status = OpenConfigFile(0, ""); break; case M_FILE_SAVE: status = SaveConfigFile(); break; case M_FILE_EXIT: CloseWindow(); break; } break; case kCM_TAB: //cout << "Tab #" << fTab->GetCurrent() << " selected" << endl; break; case kCM_COMBOBOX: if (parm1!=300) status = HandleCombo(parm1, parm2); else status = LoadConfiguration( parm2 ); break; case kCM_LISTBOX: //list box event for (i=0; iGetState()!=kButtonDisabled ) fMaximize[i]->SetState(kButtonDisabled); else break; if (parm1==200) { // numPads can only range from 1 to MAX_PADS, inclusive if (fChannelListBox->GetSelection(parm2)){ if (numPadsSelect(parm2); int entryID = GetLBID(); fPadListBox->AddEntrySort( (entry->GetText())->GetString(), entryID); fPadListBox->MapSubwindows(); fPadListBox->Layout(); //cout << "Added Entry " << (entry->GetText())->GetString() // << " ID NUM = " << entryID << endl; } } else if (numPads==1) fChannelListBox->Select(parm2, kTRUE); changedDB = kTRUE; //cout << " NUMPADS = " << numPads << endl; } if (parm1==202) { if (numPads > 1) { fPadListBox->RemoveEntry(parm2); fPadListBox->MapSubwindows(); fPadListBox->Layout(); changedDB = kTRUE; numPads--; //cout << "Removed Entry ID NUM =" << parm2 << endl; } //cout << "numPads = " << numPads << endl; } break; case kCM_BUTTON: //button event switch (parm1) { case B_QUIT: CloseWindow(); break; case B_DRAW: status = PlotMultiples(); if (status==1) for (i=0; i< numPads; i++) fMaximize[i]->SetState(kButtonUp); break; case B_PRINT: status = PrintConfigure(); break; case B_LOAD_CHAN: status = LoadChannels(); changedDB = kTRUE; break; case B_MAX1: status = MaximizePad(0); break; case B_MAX2: status = MaximizePad(1); break; case B_MAX3: status = MaximizePad(2); break; case B_MAX4: status = MaximizePad(3); break; case B_MAX5: status = MaximizePad(4); break; case B_MAX6: status = MaximizePad(5); break; case B_MAX7: status = MaximizePad(6); break; case B_MAX8: status = MaximizePad(7); break; case B_MAX9: status = MaximizePad(8); break; } break; case kCM_CHECKBUTTON: if (parm1>=40 && parm1<=43) { Bool_t somethingset = kFALSE; for( i=0; i<4; i++) if(fGrfOpts[i]->GetState() == kButtonDown) { somethingset = kTRUE; break; } if (!somethingset) { int rv; fGrfOpts[1]->SetState(kButtonDown); fGrfOpts[2]->SetState(kButtonDown); status = HandleCheck(41); status = HandleCheck(42); new TGMsgBox(fClient->GetRoot(), this, "Graph Selection Problem", "You must specify at least one Graph option", kMBIconExclamation, kMBOk, &rv); } else status = HandleCheck(parm1); } else status = HandleCheck(parm1); break; case kCM_RADIOBUTTON: //radio button event if( parm1 >= 80 && parm1 <= 83) { for( i=0; i<4; i++) if (fRadios[i]->WidgetId() != parm1) fRadios[i]->SetState(kButtonUp); } if( parm1 >= 90 && parm1 <= 94) { for( i=0; i<5; i++) if (fGrfRadios[i]->WidgetId() != parm1) fGrfRadios[i]->SetState(kButtonUp); } if( parm1 >= 60 && parm1 <= 65) { for ( i=0; i<6; i++) if (f2DType[i]->WidgetId() != parm1) f2DType[i]->SetState(kButtonUp); } if( parm1 >= 110 && parm1 <= 124) { for ( i=0; i<15; i++) if (f2DOpts[i]->WidgetId() != parm1) f2DOpts[i]->SetState(kButtonUp); } status = HandleRadio(parm1); break; default: break; } break; case kC_TEXTENTRY: //Textfield event switch (GET_SUBMSG(msg)) { case kTE_TEXTCHANGED: // if the text changes if (parm1 != 100) status = HandleText(parm1); break; case kTE_ENTER: // if the 'Return' key is typed in a textfield if (parm1 == 100) { status = LoadChannels(); changedDB = kTRUE; if ( !strcmp( fDBbuf->GetString(), "DEMO" ) ) OpenConfigFile(1, "DEMO.DPC"); // if the DEMO database is selected, load its configuration file } else status = HandleText(parm1); break; } break; default: break; } int retval; if (status==-5) { new TGMsgBox(fClient->GetRoot(), this, "Drawing Error!", "The main canvas cannot be recreated -- You should restart the program", kMBIconStop, kMBOk, &retval); } else if (status==-4) { new TGMsgBox(fClient->GetRoot(), this, "Error in Opening!", "Configuration Opening Error -- File Does Not Exist!", kMBIconStop, kMBOk, &retval); } else if (status==-3) { new TGMsgBox(fClient->GetRoot(), this, "Error in Opening!", "Configuration Opening Error -- Not a .DPC file!", kMBIconStop, kMBOk, &retval); } else if (status==-2) { new TGMsgBox(fClient->GetRoot(), this, "Error in DB Function!", "Database Opening Error -- Plotting Stopped.", kMBIconStop, kMBOk, &retval); } else if (status==-1) { new TGMsgBox(fClient->GetRoot(), this, "Error in DB Function!", "Database Scanning Error -- Plotting Stopped.", kMBIconStop, kMBOk, &retval); } else if (status!=1) { // ERROR -- Create Message Window new TGMsgBox(fClient->GetRoot(), this, "Error in Plotting!", "Indeterminate Error -- Plotting Stopped.", kMBIconStop, kMBOk, &retval); } return kTRUE; } int HVDPMainFrame::PrintConfigure() { fMyConfig->PrintAllConfigs(); return 1; } int HVDPMainFrame::GetLBID() { int i; TGTextLBEntry *entry; for (i=1; i<=MAX_PADS; i++) { entry = (TGTextLBEntry*)fPadListBox->Select(i, kFALSE); if (entry == NULL) return i; } return 0; } int HVDPMainFrame::PlotMultiples() { //if the main canvas is gone, don't draw if (gROOT->GetListOfCanvases()->FindObject("ReadbackDisplayProgram")==0) { return -5; } // Get a group of selected channel names const char *ChanGroup[MAX_PADS]; int j = 0; TGTextLBEntry *entry; for (int i = 1; i<=MAX_PADS; i++) { entry = (TGTextLBEntry*)fPadListBox->Select(i, kFALSE); if (entry!=NULL) { ChanGroup[j] = (entry->GetText())->GetString(); j++; } } //for (i = 0; iClear(); switch (numPads) { case 1: SplitCanvas(1, 1, 0.001, 0.001, 1); break; case 2: SplitCanvas(1, 2, 0.001, 0.001, 2); break; case 3: case 4: SplitCanvas(2, 2, 0.001, 0.001, 3); break; case 5: case 6: SplitCanvas(3, 2, 0.001, 0.001, 4); break; case 7: case 8: case 9: SplitCanvas(3, 3, 0.001, 0.001, 5); break; // I found that my system generated an error if you tried to have more // than 10 or so pads with Axes -- I left this part (below) of the // code in case you can make it work on another system/OS -- just change // MAX_PADS and recompile. You might also have to change the Maximize // button scheme -- R. Roth case 10: case 11: case 12: SplitCanvas(4, 3, 0.001, 0.001, 6); break; case 13: case 14: case 15: case 16: SplitCanvas(4, 4, 0.001, 0.001, 7); break; } //cout << "Canvas Split..." << endl; fC1->Update(); int status = 1; if (changedDB) { //open OBJY DB dbHV *myDB = NULL; ooHandle( ooDBObj ) my_dbh; myDB = dbHV::openDB(fDBbuf->GetString(), 'r'); if (myDB == NULL) { cout << "Error opening DB" << endl; return -2; } else my_dbh = myDB->getDBHandle(); for (i = 0; icd(); if (nx <= 0) nx = 1; if (ny <= 0) ny = 1; Int_t ix,iy; Float_t x1,y1,x2,y2; Float_t dy = 1/Float_t(ny); Float_t dx = 1/Float_t(nx); //TPad *pad; char *name = new char [strlen(fC1->GetName())+6]; Int_t n = 0; if (color == 0) color = fC1->GetFillColor(); for (iy=0;iy y2) continue; for (ix=0;ix x2) continue; n++; sprintf(name,"%s_%d",fC1->GetName(),n); fPadList[n-1] = new TPad(name,name,x1,y1,x2,y2,color); //cout << "Pad " << n-1 << " created" << endl; fPadList[n-1]->SetNumber(n); fPadList[n-1]->Draw(); } } // We need to fill the remaining slots in fPadList so that the 'delete' // code in PlotMultiple() doesn't try to delete something that is already // deleted. for (ix = n; ix< MAX_PADS; ix++) { fPadList[ix] = new TPad(); //cout << "fPadList[" << ix << "] filled with dummy" << endl; } delete [] name; fC1->Modified(); padsav->cd(); } int HVDPMainFrame::LoadChannels() { // This routine loads the channel names from the database into the listbox, // where they can be selected for plotting. It only loads those channels which actually have // readbacks, since trying to plot a channel for which there are no readbacks causes a // segmentaion/bus error. int i; if ( fCHList->IsEmpty() == 0 ) fCHList->Delete(); //get rid of old data if (numchannels != -1) { fChannelListBox->RemoveEntries(1, numchannels); fChannelListBox->Layout(); TGTextLBEntry *entry; for (i=1; i<=MAX_PADS; i++) { entry = (TGTextLBEntry*)fPadListBox->Select(i, kFALSE); if (entry!=NULL) fPadListBox->RemoveEntry(i); } // fPadListBox->RemoveEntries(1, numPads); // RemoveEntries() fails here in some cases because fPadListBox's entries // may not be in consequecutive order every time. I.e., the entry id's // might be 1, 2, 3 in one case and 2, 5, 7 in another. fPadListBox->Layout(); } //open OBJY DB dbHV *myDB = NULL; ooHandle( ooDBObj ) my_dbh; myDB = dbHV::openDB(fDBbuf->GetString(), 'r'); if (myDB == NULL) { cout << "Error opening DB" << endl; return -2; } else my_dbh = myDB->getDBHandle(); ooItr(dbHVchannel) itCh; ooItr(dbHVreadback) itRb; ooItr(dbHVmoduleContainer ) itMC; char cContainerName[256]; ooHandle( ooContObj ) hContainer; // Reworked this section so that the program doesn't search the // entire database when looking for the next channel -- only the // module container. -- RR if ( itMC.scan( my_dbh ) != oocSuccess ) { cout << "LoadChannels: error in scanning DB for module containers" << endl; return -1; } while ( itMC.next() ) { if ( itCh.scan( itMC ) != oocSuccess ) { cout << "LoadChannels: error in scanning database" << endl; return -1; } while ( itCh.next() ) { sprintf( cContainerName, "Readbacks_%s", itCh->getName() ); ooStatus iStatus = hContainer.open( my_dbh, cContainerName ); if ( iStatus != oocSuccess) { cout << "LoadChannels: Could not open readback container " << cContainerName << endl; continue; } if ( itRb.scan( hContainer ) != oocSuccess ) { cout << "LoadChannels: failure in scanning container " << cContainerName << endl; continue; } if ( itRb.next() ) //i.e., the channel actually has readbacks fCHList->Add(new TObjString(itCh->getName())); hContainer.close(); } } //Close DB delete myDB; myDB = NULL; cout << "DB closed" << endl; TObjLink *lnk = fCHList->FirstLink(); TObjString *str; fPadListBox->AddEntry( (const char *)( ((TObjString*)lnk->GetObject())->GetString() ), 1); numPads = 1; int numchan = 1; while (lnk) { str = (TObjString*)lnk->GetObject(); fChannelListBox->AddEntry( (const char*)(str->GetString()), numchan); numchan++; lnk = lnk->Next(); } numchannels = numchan - 1; //Drop last ++ from loop fChannelListBox->MapSubwindows(); fChannelListBox->Layout(); fPadListBox->MapSubwindows(); fPadListBox->Layout(); for (i=0; iGetState()!=kButtonDisabled ) fMaximize[i]->SetState(kButtonDisabled); else break; return 1; } int HVDPMainFrame::Get1DOpts( char *opts, int padindex ) { char temp[20]; int option = fMyConfig->GetPlot1DOptions(padindex); int err = fMyConfig->GetErrorBars(padindex); switch(err){ case 1: strcpy(temp, "e"); break; case 2: strcpy(temp, "e1"); break; case 3: strcpy(temp, "e2"); break; case 4: strcpy(temp, "e3"); break; default: strcpy(temp, ""); break; } if ( (option & 0x0001) == 1) { strcat(temp, "b"); } if ( (option & 0x0002) == 2) { strcat(temp, "c"); } if ( (option & 0x0004) == 4) { strcat(temp, "p"); } if ( (option & 0x0008) == 8) { strcat(temp, "l"); } if ( (option & 0x0010) == 16) { strcat(temp, "lego2"); } strcpy(opts, temp); return 1; } int HVDPMainFrame::GetGrfOpts( char *opts, int padindex ) { char temp[20]; int option = fMyConfig->GetPlotGrfOptions(padindex); strcpy(temp, "A"); //Add an axis if ( (option & 0x0001) == 1) { strcat(temp, "B"); } if ( (option & 0x0002) == 2) { strcat(temp, "C"); } if ( (option & 0x0004) == 4) { strcat(temp, "P"); } if ( (option & 0x0008) == 8) { strcat(temp, "L"); } strcpy(opts, temp); return 1; } int HVDPMainFrame::Get2DOpts( char *opts, int padindex ) { char temp[20]; int option = fMyConfig->GetPlotSubType(padindex); switch (option) { case 0: strcpy(temp, "SCAT"); break; case 1: strcpy(temp, "ARR"); break; case 2: strcpy(temp, "BOX"); break; case 3: strcpy(temp, "SURF"); break; case 4: strcpy(temp, "SURF1"); break; case 5: strcpy(temp, "SURF2"); break; case 6: strcpy(temp, "SURF3"); break; case 7: strcpy(temp, "SURF4"); break; case 8: strcpy(temp, "COL"); break; case 9: strcpy(temp, "LEGO"); break; case 10: strcpy(temp, "LEGO1"); break; case 11: strcpy(temp, "LEGO2"); break; case 12: strcpy(temp, "CONT"); break; case 13: strcpy(temp, "CONT2"); break; case 14: strcpy(temp, "CONT3"); break; } option = fMyConfig->GetPlot2DOptions(padindex); if ( (option & 0x0001) == 1) { strcat(temp, "FB"); } if ( (option & 0x0002) == 2) { strcat(temp, "BB"); } strcpy(opts, temp); return 1; } int HVDPMainFrame::LoadReadbackList(Int_t padindex, const char *chname, ooHandle(ooDBObj) my_dbh ) { if ( fRBList[padindex]->IsEmpty() == 0 ) { //cout << "LIST NOT EMPTY" << endl; fRBList[padindex]->Delete(); //get rid of old data } char cContainerName[256]; sprintf(cContainerName, "Readbacks_%s", chname); ooHandle( ooContObj ) hContainer; ooStatus iStatus = hContainer.open(my_dbh, cContainerName); if (iStatus != oocSuccess) { cout << "Error in opening readback container." << endl; return -2; } ooItr(dbHVreadback) itRb; if (itRb.scan( hContainer ) != oocSuccess ) { cout << "Failure in scanning readback container. " << endl; return -1; } // Fill sortable list structure with TRootReadBack objects numRB[padindex] = 0; double sumV, sumC, sumDV; sumV = sumC = sumDV = 0.0; while (itRb.next() ) { int enable, status; double demand, voltage, current; enable = itRb->getEnabled(); status = itRb->getStatus(); demand = itRb->getDemandVoltage(); voltage = itRb->getVoltage(); current = itRb->getCurrent(); sumV += voltage; sumC += current; sumDV += demand; fRBList[padindex]->Add(new TRootReadback( enable, status, demand, current, voltage, &( itRb->getTmTimeStamp() )) ); numRB[padindex]++; } avgV[padindex] = sumV/numRB[padindex]; avgC[padindex] = sumC/numRB[padindex]; avgDV[padindex] = sumDV/numRB[padindex]; //Compute averages to use as graphical centers return 1; } int HVDPMainFrame::FillGraph(Int_t padindex, const char *chname ) { // what to graph? int whichbutton = fMyConfig->GetTypeGraph(padindex); Char_t graphopts[20]; GetGrfOpts(graphopts, padindex); delete fHVGraph[padindex]; Float_t x[MAX_NUM_READBACKS], y[MAX_NUM_READBACKS]; char title[256]; int index = 0; time_t smallest; smallest = ((TRootReadback*)fRBList[padindex]->First())->getTime(); //cout << "SMALLEST TIME = " << smallest << endl; TRootReadback* rb; TObjLink *lnk = fRBList[padindex]->FirstLink(); while (lnk) { rb = (TRootReadback*)lnk->GetObject(); switch (whichbutton) { case 0: x[index]=(Float_t)((rb->getTime() - smallest)/60.0); // time in minutes y[index]=(Float_t)(rb->getVoltage()); break; case 1: x[index]=(Float_t)((rb->getTime() - smallest)/60.0); // time in minutes y[index]=(Float_t)(rb->getCurrent()); break; case 2: x[index]=(Float_t)((rb->getTime() - smallest)/60.0); // time in minutes y[index]=(Float_t)(rb->getDemandVoltage()); break; case 3: x[index]=(Float_t)((rb->getTime() - smallest)/60.0); y[index]=(Float_t)(rb->getStatus()); break; case 4: x[index]=(Float_t)((rb->getTime() - smallest)/60.0); y[index]=(Float_t)(rb->getEnable()); break; } index++; lnk = lnk->Next(); } fHVGraph[padindex] = new TGraph(numRB[padindex], x, y); switch (whichbutton) { case 0: sprintf(title, "Voltage (volts) vs. time : Channel %s", chname); fHVGraph[padindex]->SetMarkerColor(kRed); break; case 1: sprintf(title, "Current (microamps) vs. time : Channel %s", chname); fHVGraph[padindex]->SetMarkerColor(kBlue); break; case 2: sprintf(title, "Demand Voltage (volts) vs. time : Channel %s", chname); fHVGraph[padindex]->SetMarkerColor(kBlack); break; case 3: sprintf(title, "Status vs. time : Channel %s", chname); fHVGraph[padindex]->SetMarkerColor(kCyan); break; case 4: sprintf(title, "Enabled vs. time : Channel %s", chname); fHVGraph[padindex]->SetMarkerColor(kMagenta); break; } fPadList[padindex]->cd(); fPadList[padindex]->Clear(); fPadList[padindex]->SetGrid(); fPadList[padindex]->SetFillColor(fMyConfig->GetGraphCanvas(padindex)); ftf = fPadList[padindex]->GetFrame(); ftf->SetFillColor(fMyConfig->GetGraphBG(padindex)); fHVGraph[padindex]->SetTitle(title); fHVGraph[padindex]->SetFillColor(fMyConfig->GetGraphFill(padindex)); fHVGraph[padindex]->SetLineColor(fMyConfig->GetGraphLine(padindex)); fHVGraph[padindex]->SetMarkerStyle(fMyConfig->GetGraphMarker(padindex)); if (numPads>4) fHVGraph[padindex]->SetMarkerSize(0.5); fHVGraph[padindex]->SetLineWidth(2); fHVGraph[padindex]->Draw(graphopts); fC1->Update(); fholder = fHVGraph[padindex]->GetHistogram(); fholder->SetXTitle("Time (minutes)"); fC1->Update(); return 1; } int HVDPMainFrame::Fill2DHistogram(Int_t padindex, const char *chname) { delete f2DHisto[padindex]; //Get Plot Style Char_t styleoptions[20]; int numX = fMyConfig->GetNum2DXBins(padindex); int numY = fMyConfig->GetNum2DYBins(padindex); double vrange = fMyConfig->GetVolt2D(padindex); double crange = fMyConfig->GetCurr2D(padindex); Get2DOpts(styleoptions, padindex); char title[256]; int whichbutton = fMyConfig->GetType2D(padindex); time_t smallest = ((TRootReadback*)fRBList[padindex]->First())->getTime(); time_t largest = ((TRootReadback*)fRBList[padindex]->Last())->getTime(); largest -= smallest; largest /= 60.0; // change to time in minutes char histoname[128]; switch (whichbutton) { case 0: sprintf(histoname, "V&C_%d", padindex+1); break; case 1: sprintf(histoname, "V&T_%d", padindex+1); break; case 2: sprintf(histoname, "V&DV_%d", padindex+1); break; case 3: sprintf(histoname, "C&T_%d", padindex+1); break; case 4: sprintf(histoname, "DV&C_%d", padindex+1); break; case 5: sprintf(histoname, "DV&T_%d", padindex+1); break; } switch (whichbutton) { case 0: sprintf(title, "Voltage And Current Distribution : Channel %s", chname); f2DHisto[padindex] = new TH2D(histoname, title, numX, avgV[padindex]-vrange, avgV[padindex]+vrange, numY, avgC[padindex]-crange, avgC[padindex]+crange); break; case 1: sprintf(title, "Voltage over Time : Channel %s", chname); f2DHisto[padindex] = new TH2D(histoname, title, numX, avgV[padindex]-vrange, avgV[padindex]+vrange, numRB[padindex], 0, largest); break; case 2: sprintf(title, "Voltage And Demand Voltage Distribution : Channel %s", chname); f2DHisto[padindex] = new TH2D(histoname, title, numX, avgV[padindex]-vrange, avgV[padindex]+vrange, numY, avgDV[padindex]-vrange, avgDV[padindex]+vrange); break; case 3: sprintf(title, "Current over Time : Channel %s", chname); f2DHisto[padindex] = new TH2D(histoname, title, numX, avgC[padindex]-crange, avgC[padindex]+crange, numRB[padindex], 0, largest); break; case 4: sprintf(title, "Demand Voltage And Current Distribution : Channel %s", chname); f2DHisto[padindex] = new TH2D(histoname, title, numX, avgV[padindex]-vrange, avgV[padindex]+vrange, numY, avgC[padindex]-crange, avgC[padindex]+crange); break; case 5: sprintf(title, "Demand Voltage over Time : Channel %s", chname); f2DHisto[padindex] = new TH2D(histoname, title, numX, avgV[padindex]-vrange, avgV[padindex]+vrange, numRB[padindex], 0, largest); break; } TRootReadback* rb; TObjLink *lnk = fRBList[padindex]->FirstLink(); while (lnk) { rb = (TRootReadback*)lnk->GetObject(); switch (whichbutton){ case 0: f2DHisto[padindex]->Fill( (Axis_t)( rb->getVoltage() ), (Axis_t)( rb->getCurrent() ) ); break; case 1: f2DHisto[padindex]->Fill( (Axis_t)( rb->getVoltage() ), (Axis_t)( ((rb->getTime())-smallest)/60.0) ); break; case 2: f2DHisto[padindex]->Fill( (Axis_t)( rb->getVoltage() ), (Axis_t)( rb->getDemandVoltage() ) ); break; case 3: f2DHisto[padindex]->Fill( (Axis_t)( rb->getCurrent() ), (Axis_t)( ((rb->getTime())-smallest)/60.0) ); break; case 4: f2DHisto[padindex]->Fill( (Axis_t)( rb->getDemandVoltage() ), (Axis_t)( rb->getCurrent() ) ); break; case 5: f2DHisto[padindex]->Fill( (Axis_t)( rb->getDemandVoltage() ), (Axis_t)( ((rb->getTime())-smallest)/60.0) ); break; } lnk = lnk->Next(); } fPadList[padindex]->cd(); fPadList[padindex]->Clear(); fPadList[padindex]->SetGrid(); fPadList[padindex]->SetFillColor(21); f2DHisto[padindex]->SetMarkerColor(kRed); f2DHisto[padindex]->SetMarkerStyle(7); f2DHisto[padindex]->SetLabelSize(0.03); f2DHisto[padindex]->SetContour(50); f2DHisto[padindex]->SetFillColor(45); f2DHisto[padindex]->Draw(styleoptions); fC1->Update(); return 1; } int HVDPMainFrame::FillHistogram(Int_t padindex, const char *chname) { delete fHisto[padindex]; // what to graph? int whichbutton = fMyConfig->GetType1D(padindex); int numbins1D = fMyConfig->GetNum1DBins(padindex); int vrange = fMyConfig->GetVolt1D(padindex); int crange = fMyConfig->GetCurr1D(padindex); Char_t draw1Dopts[20]; Get1DOpts( draw1Dopts, padindex ); //cout << padindex << ") DRAW OPTS = " << draw1Dopts << endl; char histoname[128]; switch (whichbutton) { case 0: sprintf(histoname, "Voltages_%d", padindex+1); break; case 1: sprintf(histoname, "Currents_%d", padindex+1); break; case 2: sprintf(histoname, "DVoltage_%d", padindex+1); break; case 3: sprintf(histoname, "V&DV_%d", padindex+1); break; } char title[256]; switch (whichbutton) { case 0: sprintf(title, "Voltage Distribution : Channel %s", chname); fHisto[padindex] = new TH1D(histoname, title, numbins1D, avgV[padindex]-vrange, avgV[padindex]+vrange); fHisto[padindex]->SetMarkerColor(kRed); break; case 1: sprintf(title, "Current Distribution : Channel %s", chname); fHisto[padindex] = new TH1D(histoname, title, numbins1D, avgC[padindex]-crange, avgC[padindex]+crange); fHisto[padindex]->SetMarkerColor(kBlue); break; case 2: sprintf(title, "Demand Voltage Distribution : Channel %s", chname); fHisto[padindex] = new TH1D(histoname, title, numbins1D, avgDV[padindex]-vrange, avgDV[padindex]+vrange); fHisto[padindex]->SetMarkerColor(kBlack); break; case 3: if (strstr(draw1Dopts, "lego2")!=NULL) sprintf(title, "Voltage and DV Distribution : Channel %s", chname); else sprintf(title, "Voltage Distribution : Channel %s", chname); delete fHisto2[padindex]; fHisto[padindex] = new TH1D(histoname, title, numbins1D, avgV[padindex]-vrange, avgV[padindex]+vrange); sprintf(histoname, "DV&V_%d", padindex+1); fHisto2[padindex] = new TH1D(histoname, title, numbins1D, avgDV[padindex]-vrange, avgDV[padindex]+vrange); fHisto2[padindex]->SetMarkerColor(kBlack); fHisto[padindex]->SetMarkerColor(kRed); break; } TRootReadback* rb; TObjLink *lnk = fRBList[padindex]->FirstLink(); while (lnk) { rb = (TRootReadback*)lnk->GetObject(); switch (whichbutton) { case 0: fHisto[padindex]->Fill(rb->getVoltage()); break; case 1: fHisto[padindex]->Fill(rb->getCurrent()); break; case 2: fHisto[padindex]->Fill(rb->getDemandVoltage()); break; case 3: fHisto[padindex]->Fill(rb->getVoltage()); fHisto2[padindex]->Fill(rb->getDemandVoltage()); break; } lnk = lnk->Next(); } if (whichbutton!=3 || (strstr(draw1Dopts, "lego2")!=NULL) ) { fPadList[padindex]->cd(); fPadList[padindex]->Clear(); fPadList[padindex]->SetGrid(); fPadList[padindex]->SetFillColor(21); fHisto[padindex]->SetFillColor(fMyConfig->GetFill1(padindex)); fHisto[padindex]->SetLineColor(fMyConfig->GetLine1(padindex)); fHisto[padindex]->SetMarkerStyle(fMyConfig->GetMarker1D(padindex)); if (numPads>4) fHisto[padindex]->SetMarkerSize(0.5); fHisto[padindex]->SetLabelSize(0.03); fHisto[padindex]->SetLineWidth(2); fHisto[padindex]->Draw(draw1Dopts); fC1->Update(); } else { //Overlay Demand Voltage histogram on top of Voltage histogram (non-lego plot) fPadList[padindex]->cd(); fPadList[padindex]->Clear(); fPadList[padindex]->SetGrid(); fPadList[padindex]->SetFillColor(21); fHisto[padindex]->SetFillColor(fMyConfig->GetFill1(padindex)); fHisto[padindex]->SetLineColor(fMyConfig->GetLine1(padindex)); fHisto[padindex]->SetMarkerStyle(fMyConfig->GetMarker1D(padindex)); if (numPads>4) fHisto[padindex]->SetMarkerSize(0.5); fHisto[padindex]->SetLabelSize(0.03); fHisto[padindex]->SetLineWidth(2); fHisto[padindex]->Draw(draw1Dopts); fHisto2[padindex]->SetFillColor(fMyConfig->GetFill2(padindex)); fHisto2[padindex]->SetLineColor(fMyConfig->GetLine2(padindex)); fHisto2[padindex]->SetMarkerStyle(fMyConfig->GetMarker1D(padindex)); if (numPads>4) fHisto2[padindex]->SetMarkerSize(0.5); fHisto2[padindex]->SetLabelSize(0.03); fHisto2[padindex]->SetLineWidth(2); char ctemp[20]; strcpy(ctemp, draw1Dopts); strcat(ctemp, "same"); fHisto2[padindex]->Draw(ctemp); fC1->Update(); } return 1; } ////////////////////////////////////////////////////////////// //Statements that are included in almost every ROOT GUI app // ////////////////////////////////////////////////////////////// extern void InitGui(); VoidFuncPtr_t initfuncs[] = {InitGui, 0 }; TROOT root("GUI", "HV HISTOGRAM DISPLAY PROGRAM", initfuncs); int main(int argc, char **argv) { for (int i=0; iGetRoot(), 570, 200, argc, argv); theApp.Run(); return 0; }