Changeset 138
- Timestamp:
- 12/11/09 09:28:16 (15 years ago)
- Location:
- Evidence/Edd
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
Evidence/Edd
- Property svn:ignore
-
old new 1 1 Edd 2 2 Makefile 3 moc c_Edd.cpp3 moc_Edd.cpp
-
- Property svn:ignore
-
Evidence/Edd/Edd.cc
r136 r138 10 10 11 11 #include "Edd.h" 12 13 Qt::GlobalColor LineColors[] = {Qt::black, Qt::blue, Qt::red, Qt::green, Qt::white, 14 Qt::darkRed, Qt::darkGreen, Qt::darkBlue, Qt::cyan, 15 Qt::darkCyan, Qt::magenta, Qt::darkMagenta, 16 Qt::gray, Qt::darkGray, Qt::lightGray}; 12 17 13 18 ////////////////////////////////////////// … … 16 21 17 22 // Constructor 18 FCS_Indicator::FCS_Indicator(char *DIMService, QWidget *P): QLineEdit(P) {23 Edd_Indicator::Edd_Indicator(char *DIMService, QWidget *P): QLineEdit(P) { 19 24 20 25 ServiceName = new char [strlen(DIMService)+1]; … … 31 36 32 37 // Destructor 33 FCS_Indicator::~FCS_Indicator() {38 Edd_Indicator::~Edd_Indicator() { 34 39 delete Data; 35 40 delete[] ServiceName; … … 37 42 38 43 // Handling of DIM service update 39 void FCS_Indicator::infoHandler() {44 void Edd_Indicator::infoHandler() { 40 45 41 46 // Check if service available … … 74 79 75 80 // Open plot if mouse release within widget 76 void FCS_Indicator::mouseReleaseEvent(QMouseEvent *Event) {81 void Edd_Indicator::mouseReleaseEvent(QMouseEvent *Event) { 77 82 78 83 if (Event->button()==Qt::LeftButton && contentsRect().contains(Event->pos())) { 79 FCS_Plot *Graph = new FCS_Plot(ServiceName, NULL);84 Edd_Plot *Graph = new Edd_Plot(ServiceName, NULL); 80 85 Graph->show(); 81 86 } … … 83 88 84 89 // Handling of mouse press event: Register start position for drag 85 void FCS_Indicator::mousePressEvent(QMouseEvent *Event) {90 void Edd_Indicator::mousePressEvent(QMouseEvent *Event) { 86 91 87 92 if (Event->button() == Qt::LeftButton) dragStart = Event->pos(); … … 89 94 90 95 // Handling of dragging (Drag and MimeData will be deleted by Qt) 91 void FCS_Indicator::mouseMoveEvent(QMouseEvent *Event) {96 void Edd_Indicator::mouseMoveEvent(QMouseEvent *Event) { 92 97 93 98 if ((Event->buttons() & Qt::LeftButton) == 0) return; … … 109 114 // Constructor 110 115 // 111 FCS_Plot::FCS_Plot(char *DIMService, QWidget *P): QwtPlot(P) { 112 113 // Generate name of DIM history service 114 if (asprintf(&Name, "%s.hist", DIMService) == -1) { 115 QMessageBox::warning(this, "Error","Could not generate service name with asprintf()",QMessageBox::Ok); 116 Name = NULL; 117 return; 118 } 119 120 // Enable drag&drop 116 Edd_Plot::Edd_Plot(char *DIMService, QWidget *P): QwtPlot(P) { 117 121 118 setAcceptDrops(true); 122 119 123 120 // Graph properties 124 setAxisTitle(QwtPlot::xBottom, "Time"); 125 setAxisTitle(QwtPlot::yLeft, Name); 121 QwtText XAxisTitle("Time (RJD-55000)"); 122 XAxisTitle.setFont(QFont("Helvetica", 10)); 123 setAxisTitle(QwtPlot::xBottom, XAxisTitle); 126 124 setAutoReplot(false); 127 125 setCanvasBackground(QColor(Qt::yellow)); … … 134 132 Grid->setMajPen(QPen(Qt::gray, 0, Qt::DotLine)); 135 133 Grid->attach(this); 136 Signal = new QwtPlotCurve;137 Signal->attach(this);138 134 Legend = new QwtLegend(); 135 insertLegend(Legend, QwtPlot::TopLegend); 136 139 137 // Threads may not call replot directly, but only through this signal 140 connect(this, SIGNAL(YEP()), this, SLOT( replot()));138 connect(this, SIGNAL(YEP()), this, SLOT(UpdatePlot())); 141 139 142 140 // Context menu 143 141 Menu = new QMenu(this); 144 YLogAction = Menu->addAction("y scale log", this, SLOT( MenuYScale()));142 YLogAction = Menu->addAction("y scale log", this, SLOT(UpdatePlot())); 145 143 YLogAction->setCheckable(true); 144 NormAction = Menu->addAction("Normalize", this, SLOT(UpdatePlot())); 145 NormAction->setCheckable(true); 146 146 Menu->addAction("Zoom out", this, SLOT(MenuZoomOut())); 147 NormAction = Menu->addAction("Normalize"); 148 NormAction->setCheckable(true); 147 Menu->addAction("Single trace", this, SLOT(MenuSingleTrace())); 149 148 Menu->addSeparator(); 150 149 Menu->addAction("Save plot", this, SLOT(MenuSave())); … … 152 151 153 152 // DIM client 154 Data = new DimStampedInfo(Name, NO_LINK, this);153 AddService(DIMService); 155 154 } 156 155 … … 158 157 // Destructor (items with parent widget are automatically deleted) 159 158 // 160 FCS_Plot::~FCS_Plot() { 161 free(Name); 162 163 delete Data; delete Signal; delete Grid; 159 Edd_Plot::~Edd_Plot() { 160 161 for (int i=0; i<Items.size(); i++) { 162 delete Items[i].Data; 163 delete Items[i].Signal; 164 delete[] Items[i].x; 165 delete[] Items[i].y; 166 } 167 delete Grid; 168 } 169 170 // 171 // Add history service to plot 172 // 173 void Edd_Plot::AddService(char *DIMService) { 174 175 // Generate name of DIM service 176 QString Name(DIMService); 177 Name.append(".hist"); 178 179 // Lock this thread (because infoHandler() might be called before list insertion) 180 QMutexLocker Locker(&Mutex); 181 182 // Generate new curve and subscribe to service 183 struct PlotItem New; 184 New.Signal = new QwtPlotCurve; 185 New.Signal->attach(this); 186 New.Signal->setTitle(Name); 187 New.Signal->setPen(QColor(LineColors[Items.size()%(sizeof(LineColors)/sizeof(Qt::GlobalColor))])); 188 New.x = NULL; 189 New.y = NULL; 190 New.Data = new DimStampedInfo(Name.toAscii(), NO_LINK, this); 191 192 Items.append(New); 164 193 } 165 194 … … 167 196 // Handle update of DIM service 168 197 // 169 void FCS_Plot::infoHandler() {198 void Edd_Plot::infoHandler() { 170 199 171 200 // Check if service available 172 201 if (getInfo()->getSize() == strlen(NO_LINK)+1 && strcmp(getInfo()->getString(), NO_LINK) == 0) { 173 setStatusTip(QString("%1: unavailable").arg( Name));202 setStatusTip(QString("%1: unavailable").arg(getInfo()->getName())); 174 203 return; 175 204 } 176 205 206 // Lock this thread (see AddService()) 207 QMutexLocker Locker(&Mutex); 208 209 // Determine which plot item this call belongs to 210 int ItemNo; 211 for (ItemNo=0; ItemNo<Items.size(); ItemNo++) if (Items[ItemNo].Data == getInfo()) break; 212 if (ItemNo == Items.size()) return; // safety check 213 177 214 EvidenceHistoryItem *Curr = (EvidenceHistoryItem *) getInfo()->getData(); 178 int Count=0, Items = getInfo()->getSize()/sizeof(struct EvidenceHistoryItem); 179 180 double *x = new double [Items]; 181 double *y = new double [Items]; 215 int Count=0, DataPoints = getInfo()->getSize()/sizeof(struct EvidenceHistoryItem); 216 217 delete[] Items[ItemNo].x; 218 delete[] Items[ItemNo].y; 219 Items[ItemNo].x = new double [DataPoints]; 220 Items[ItemNo].y = new double [DataPoints]; 182 221 183 222 // Find oldest item 184 223 int Oldest; 185 for (Oldest=1; Oldest< Items; Oldest++) {224 for (Oldest=1; Oldest<DataPoints; Oldest++) { 186 225 if (Curr[Oldest].Seconds < Curr[Oldest-1].Seconds) break; 187 226 } 188 227 189 228 // Plot data starting with oldest value 190 for (int i=0; i< Items; i++) {191 x[Count] = (double) Curr[(i+Oldest)%Items].Seconds;192 y[Count] = Curr[(i+Oldest)%Items].Value;193 if ( x[Count] != 0) Count++;229 for (int i=0; i<DataPoints; i++) { 230 Items[ItemNo].x[Count] = (double) Curr[(i+Oldest)%DataPoints].Seconds; 231 Items[ItemNo].y[Count] = Curr[(i+Oldest)%DataPoints].Value; 232 if (Items[ItemNo].x[Count] != 0) Count++; 194 233 } 195 234 … … 197 236 double Smallest = DBL_MAX, Largest = DBL_MIN; 198 237 for (int i=0; i<Count; i++) { 199 if (Largest < y[i]) Largest = y[i]; 200 if (Smallest > y[i]) Smallest = y[i]; 201 } 202 203 // Adapt time scale and normalize y scale if requested 204 for (int i=Count-1; i>=0; i--) { 205 x[i] = x[i]-x[0]; 206 if (NormAction->isChecked()) { 207 if (Smallest != Largest) y[i] = (y[i] - Smallest)/(Largest-Smallest); 208 else y[i] = 1; 209 } 210 } 211 212 // Plot datas 213 Signal->setData(x, y, Count); 214 Signal->show(); 215 Zoomer->setZoomBase(Signal->boundingRect()); 216 emit YEP(); // Direct drawing within thread illegal! 217 218 delete[] x; 219 delete[] y; 220 238 if (Largest < Items[ItemNo].y[i]) Largest = Items[ItemNo].y[i]; 239 if (Smallest > Items[ItemNo].y[i]) Smallest = Items[ItemNo].y[i]; 240 } 241 Items[ItemNo].Smallest = Smallest; 242 Items[ItemNo].Largest = Largest; 243 Items[ItemNo].Count = Count; 244 221 245 // Update status tip 222 246 QDateTime Time = QDateTime::fromTime_t(getInfo()->getTimestamp()); 223 setStatusTip(QString("%1: Last update %2 Format '%3'").arg(Name, Time.toString()).arg(getInfo()->getFormat())); 247 setStatusTip(QString("%1: Last update %2 Format '%3'").arg(getInfo()->getName(), Time.toString()).arg(getInfo()->getFormat())); 248 249 emit(YEP()); 250 } 251 252 253 // 254 // Update all curves in plot 255 // 256 void Edd_Plot::UpdatePlot() { 257 258 QMutexLocker Locker(&Mutex); 259 260 if (!YLogAction->isChecked()) { 261 setAxisScaleEngine(QwtPlot::yLeft, new QwtLinearScaleEngine); 262 } 263 else setAxisScaleEngine(QwtPlot::yLeft, new QwtLog10ScaleEngine); 264 265 for (int ItemNo=0; ItemNo<Items.size(); ItemNo++) { 266 267 double *x = new double [Items[ItemNo].Count]; 268 double *y = new double [Items[ItemNo].Count]; 269 270 // Adapt time scale and normalize y scale if requested 271 for (int i=0; i<Items[ItemNo].Count; i++) { 272 x[i] = Items[ItemNo].x[i]/86400 + 40587.5 - 55000; 273 y[i] = Items[ItemNo].y[i]; 274 if (NormAction->isChecked()) { 275 if (Items[ItemNo].Smallest != Items[ItemNo].Largest) y[i] = (Items[ItemNo].y[i] - Items[ItemNo].Smallest)/(Items[ItemNo].Largest-Items[ItemNo].Smallest); 276 else y[i] = 1; 277 } 278 } 279 280 // Plot datas 281 Items[ItemNo].Signal->setData(x, y, Items[ItemNo].Count); 282 Items[ItemNo].Signal->show(); 283 Zoomer->setZoomBase(Items[ItemNo].Signal->boundingRect()); 284 285 delete[] x; 286 delete[] y; 287 } 288 replot(); 224 289 } 225 290 … … 227 292 // Reset graph axes to autoscale when fully unzoomed 228 293 // 229 void FCS_Plot::HandleZoom(const QwtDoubleRect &) {294 void Edd_Plot::HandleZoom(const QwtDoubleRect &) { 230 295 231 296 if(Zoomer->zoomRectIndex() == 0) { … … 236 301 237 302 // 238 // Drag and drop method e239 // 240 241 void FCS_Plot::dragEnterEvent(QDragEnterEvent *Event) {303 // Drag and drop methods 304 // 305 306 void Edd_Plot::dragEnterEvent(QDragEnterEvent *Event) { 242 307 243 308 if (Event->mimeData()->hasFormat("text/plain")) Event->acceptProposedAction(); 244 309 } 245 310 246 void FCS_Plot::dropEvent(QDropEvent *Event) { 247 248 FCS_Plot *Graph = new FCS_Plot(Event->mimeData()->text().toAscii().data(), NULL); 249 Graph->show(); 311 void Edd_Plot::dropEvent(QDropEvent *Event) { 312 313 AddService(Event->mimeData()->text().toAscii().data()); 250 314 } 251 315 … … 253 317 // Context menu and its functions 254 318 // 255 void FCS_Plot::contextMenuEvent(QContextMenuEvent *Event) {319 void Edd_Plot::contextMenuEvent(QContextMenuEvent *Event) { 256 320 257 321 Menu->exec(Event->globalPos()); 258 322 } 259 323 260 void FCS_Plot::MenuYScale() { 261 262 if (!YLogAction->isChecked()) { 263 setAxisScaleEngine(QwtPlot::yLeft, new QwtLinearScaleEngine); 264 } 265 else setAxisScaleEngine(QwtPlot::yLeft, new QwtLog10ScaleEngine); 266 emit YEP(); 267 } 268 269 void FCS_Plot::MenuZoomOut() { 324 void Edd_Plot::MenuZoomOut() { 270 325 271 326 Zoomer->zoom(0); … … 273 328 } 274 329 275 void FCS_Plot::MenuPrint() { 330 void Edd_Plot::MenuSingleTrace() { 331 332 QMutexLocker Locker(&Mutex); 333 334 while (Items.size() > 1) { 335 delete Items.last().Data; 336 delete Items.last().Signal; 337 delete[] Items.last().x; 338 delete[] Items.last().y; 339 Items.takeLast(); 340 } 341 emit(YEP()); 342 } 343 344 void Edd_Plot::MenuPrint() { 276 345 277 346 QPrinter *Printer = new QPrinter; … … 285 354 } 286 355 287 void FCS_Plot::MenuSave() {356 void Edd_Plot::MenuSave() { 288 357 289 358 QString Filename = QFileDialog::getSaveFileName(this, … … 309 378 310 379 // TextBox for value 311 Value = new FCS_Indicator((char *) "SQM/NSB", Central);312 Graph = new FCS_Plot((char *) "SQM/NSB", Central);313 314 Value1 = new FCS_Indicator((char *) "BIAS/VOLT/ID00/00-000", Central);315 //Graph1 = new FCS_Plot((char *) "BIAS/VOLT/ID00/00-000", Central);380 Value = new Edd_Indicator((char *) "SQM/NSB", Central); 381 Graph = new Edd_Plot((char *) "SQM/NSB", Central); 382 383 Value1 = new Edd_Indicator((char *) "BIAS/VOLT/ID00/00-000", Central); 384 //Graph1 = new Edd_Plot((char *) "BIAS/VOLT/ID00/00-000", Central); 316 385 317 386 // Clock (updated every second) … … 345 414 char *Item; 346 415 if (asprintf(&Item, "BIAS/VOLT/ID00/00-%.3d", i) != -1) { 347 Value = new FCS_Indicator(Item, NULL);416 Value = new Edd_Indicator(Item, NULL); 348 417 BiasLayout->addWidget(Value, i%10, 0+i/10, 1, 1); 349 418 free(Item); 350 419 } 351 420 if (asprintf(&Item, "BIAS/VOLT/ID00/01-%.3d", i) != -1) { 352 Value = new FCS_Indicator(Item, NULL);421 Value = new Edd_Indicator(Item, NULL); 353 422 BiasLayout->addWidget(Value, i%10, 2+i/10, 1, 1); 423 free(Item); 424 } 425 } 426 427 EnvironmentWidget = new QWidget(); 428 EnvironmentLayout = new QGridLayout(EnvironmentWidget); 429 for (int i=0; i<10; i++) { 430 char *Item; 431 if (asprintf(&Item, "ARDUINO/VAL%.2d", i) != -1) { 432 Value = new Edd_Indicator(Item, NULL); 433 EnvironmentLayout->addWidget(Value, i%5, i/5, 1, 1); 354 434 free(Item); 355 435 } … … 360 440 TabWidget->addTab(MainWidget, "&Main"); 361 441 TabWidget->addTab(BiasWidget, "&Bias"); 362 //TabWidget->addTab(EventHeaderDisplay, "&Environment"); 442 TabWidget->addTab(EnvironmentWidget, "&Environment"); 443 444 // Menu bar 445 QMenu* Menu = menuBar()->addMenu("&Menu"); 446 Menu->addAction("About", this, SLOT(MenuAbout())); 447 Menu->addSeparator(); 448 QAction* QuitAction = Menu->addAction("Quit", qApp, SLOT(quit())); 449 QuitAction->setShortcut(Qt::CTRL + Qt::Key_Q); 363 450 } 364 451 365 366 452 GUI::~GUI() { 367 453 delete Central; 368 454 } 369 455 456 void GUI::MenuAbout() { 457 QMessageBox::about(this, "About Edd","Evidence Data Display\n\n" 458 "Written by Oliver Grimm, IPP, ETH Zurich\n" 459 "EMail: oliver.grimm@phys.ethz.ch\n" 460 "This version compiled "__DATE__".\n" 461 "subversion revision "SVN_REVISION".\n\n" 462 "Graphical user interface implemented with Qt.\n" 463 "Evidence control system based on DIM (http://dim.web.cern.ch)."); 464 printf("Revision: $Revision$\n"); 465 } 370 466 371 467 //--------------------------------------------------------------------- -
Evidence/Edd/Edd.h
-
Property svn:keywords
set to
Revision
r136 r138 1 #ifndef EDD_H_SEEN 2 #define EDD_H_SEEN 3 1 4 #include <QtGui> 2 5 3 6 #include <qwt_plot.h> 4 7 #include <qwt_plot_curve.h> … … 10 13 #include <qwt_scale_widget.h> 11 14 #include <qwt_plot_layout.h> 15 #include <qwt_legend.h> 16 #include <qwt_legend_item.h> 12 17 13 18 #include <limits.h> … … 18 23 19 24 #define NO_LINK "__&DIM&NOLINK&__" // for checking if DIMserver is alive 20 25 #define SVN_REVISION "$Revision$" 26 21 27 // General indicator for DIM service 22 class FCS_Indicator: public QLineEdit, public DimClient, public DimBrowser {28 class Edd_Indicator: public QLineEdit, public DimClient, public DimBrowser { 23 29 Q_OBJECT 24 30 … … 34 40 35 41 public: 36 FCS_Indicator(char*, QWidget* = NULL);37 ~ FCS_Indicator();42 Edd_Indicator(char*, QWidget* = NULL); 43 ~Edd_Indicator(); 38 44 39 45 signals: … … 42 48 43 49 // Graph class for history display 44 class FCS_Plot: public QwtPlot, public DimClient {50 class Edd_Plot: public QwtPlot, public DimClient { 45 51 Q_OBJECT 46 52 47 char *Name; 48 DimInfo *Data; 49 void infoHandler(); 53 struct PlotItem { 54 DimInfo *Data; 55 QwtPlotCurve *Signal; 56 double *x; 57 double *y; 58 int Count; 59 double Smallest; 60 double Largest; 61 }; 50 62 63 QList<struct PlotItem> Items; 64 QMutex Mutex; 65 51 66 QMenu *Menu; 52 67 QAction *YLogAction; … … 55 70 QwtPlotPanner *Panner; 56 71 QwtPlotGrid *Grid; 57 QwtPlotCurve *Signal;58 72 QwtPlotZoomer *Zoomer; 59 73 QwtLegend *Legend; 74 75 void AddService(char *); 76 void infoHandler(); 60 77 void dragEnterEvent(QDragEnterEvent *); 61 78 void dropEvent(QDropEvent *); 62 79 63 80 public: 64 FCS_Plot(char*, QWidget* = NULL);65 ~ FCS_Plot();81 Edd_Plot(char *, QWidget * = NULL); 82 ~Edd_Plot(); 66 83 67 private slots: 84 private slots: 85 void UpdatePlot(); 68 86 void HandleZoom(const QwtDoubleRect &); 69 87 void contextMenuEvent(QContextMenuEvent *); 70 void MenuYScale();71 88 void MenuZoomOut(); 89 void MenuSingleTrace(); 72 90 void MenuSave(); 73 91 void MenuPrint(); … … 82 100 Q_OBJECT 83 101 84 FCS_Indicator *Value, *Value1;85 FCS_Plot *Graph, *Graph1;102 Edd_Indicator *Value, *Value1; 103 Edd_Plot *Graph, *Graph1; 86 104 QwtAnalogClock *Clock; 87 105 88 QWidget *Central, *MainWidget, *BiasWidget ;89 QGridLayout *MainLayout, *BiasLayout ;106 QWidget *Central, *MainWidget, *BiasWidget, *EnvironmentWidget; 107 QGridLayout *MainLayout, *BiasLayout, *EnvironmentLayout; 90 108 91 109 QTabWidget *TabWidget; 92 110 93 111 void closeEvent(QCloseEvent *); 94 112 95 113 public: 96 114 GUI(); 97 115 ~GUI(); 116 117 private slots: 118 void MenuAbout(); 98 119 }; 120 121 #endif -
Property svn:keywords
set to
Note:
See TracChangeset
for help on using the changeset viewer.