Changeset 138


Ignore:
Timestamp:
Dec 11, 2009, 9:28:16 AM (11 years ago)
Author:
ogrimm
Message:
Updates
Location:
Evidence/Edd
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • Evidence/Edd

    • Property svn:ignore
      •  

        old new  
        11Edd
        22Makefile
        3 mocc_Edd.cpp
         3moc_Edd.cpp
  • Evidence/Edd/Edd.cc

    r136 r138  
    1010
    1111#include "Edd.h"
     12
     13Qt::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};
    1217
    1318//////////////////////////////////////////
     
    1621
    1722// Constructor
    18 FCS_Indicator::FCS_Indicator(char *DIMService, QWidget *P): QLineEdit(P) {
     23Edd_Indicator::Edd_Indicator(char *DIMService, QWidget *P): QLineEdit(P) {
    1924
    2025  ServiceName = new char [strlen(DIMService)+1];
     
    3136
    3237// Destructor
    33 FCS_Indicator::~FCS_Indicator() {
     38Edd_Indicator::~Edd_Indicator() {
    3439  delete Data;
    3540  delete[] ServiceName;
     
    3742
    3843// Handling of DIM service update
    39 void FCS_Indicator::infoHandler() {
     44void Edd_Indicator::infoHandler() {
    4045
    4146  // Check if service available
     
    7479
    7580// Open plot if mouse release within widget
    76 void FCS_Indicator::mouseReleaseEvent(QMouseEvent *Event) {
     81void Edd_Indicator::mouseReleaseEvent(QMouseEvent *Event) {
    7782
    7883  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);
    8085    Graph->show();
    8186  }
     
    8388
    8489// Handling of mouse press event: Register start position for drag
    85 void FCS_Indicator::mousePressEvent(QMouseEvent *Event) {
     90void Edd_Indicator::mousePressEvent(QMouseEvent *Event) {
    8691
    8792  if (Event->button() == Qt::LeftButton) dragStart = Event->pos();
     
    8994
    9095// Handling of dragging (Drag and MimeData will be deleted by Qt)
    91 void FCS_Indicator::mouseMoveEvent(QMouseEvent *Event) {
     96void Edd_Indicator::mouseMoveEvent(QMouseEvent *Event) {
    9297
    9398  if ((Event->buttons() & Qt::LeftButton) == 0) return;
     
    109114// Constructor
    110115//
    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
     116Edd_Plot::Edd_Plot(char *DIMService, QWidget *P): QwtPlot(P) {
     117
    121118  setAcceptDrops(true);
    122119
    123120  // 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);
    126124  setAutoReplot(false);
    127125  setCanvasBackground(QColor(Qt::yellow));
     
    134132  Grid->setMajPen(QPen(Qt::gray, 0, Qt::DotLine));
    135133  Grid->attach(this);
    136   Signal = new QwtPlotCurve;
    137   Signal->attach(this);
    138 
     134  Legend = new QwtLegend();
     135  insertLegend(Legend, QwtPlot::TopLegend);
     136   
    139137  // 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()));
    141139
    142140  // Context menu
    143141  Menu = new QMenu(this);
    144   YLogAction = Menu->addAction("y scale log", this, SLOT(MenuYScale()));
     142  YLogAction = Menu->addAction("y scale log", this, SLOT(UpdatePlot()));
    145143  YLogAction->setCheckable(true);
     144  NormAction = Menu->addAction("Normalize", this, SLOT(UpdatePlot()));
     145  NormAction->setCheckable(true);
    146146  Menu->addAction("Zoom out", this, SLOT(MenuZoomOut()));
    147   NormAction = Menu->addAction("Normalize");
    148   NormAction->setCheckable(true);
     147  Menu->addAction("Single trace", this, SLOT(MenuSingleTrace()));
    149148  Menu->addSeparator();
    150149  Menu->addAction("Save plot", this, SLOT(MenuSave()));
     
    152151
    153152  // DIM client
    154   Data = new DimStampedInfo(Name, NO_LINK, this);
     153  AddService(DIMService);
    155154}
    156155
     
    158157// Destructor (items with parent widget are automatically deleted)
    159158//
    160 FCS_Plot::~FCS_Plot() {
    161   free(Name);
    162 
    163   delete Data;  delete Signal;  delete Grid;
     159Edd_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//
     173void 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);
    164193}
    165194
     
    167196// Handle update of DIM service
    168197//
    169 void FCS_Plot::infoHandler() {
     198void Edd_Plot::infoHandler() {
    170199
    171200  // Check if service available
    172201  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()));
    174203    return;
    175204  }
    176205
     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 
    177214  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];
    182221
    183222  // Find oldest item
    184223  int Oldest;
    185   for (Oldest=1; Oldest<Items; Oldest++) {
     224  for (Oldest=1; Oldest<DataPoints; Oldest++) {
    186225    if (Curr[Oldest].Seconds < Curr[Oldest-1].Seconds) break;
    187226  }
    188227
    189228  // 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++;
    194233  }
    195234 
     
    197236  double Smallest = DBL_MAX, Largest = DBL_MIN;
    198237  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 
    221245  // Update status tip
    222246  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//
     256void 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();
    224289}
    225290
     
    227292// Reset graph axes to autoscale when fully unzoomed
    228293//
    229 void FCS_Plot::HandleZoom(const QwtDoubleRect &) {
     294void Edd_Plot::HandleZoom(const QwtDoubleRect &) {
    230295
    231296  if(Zoomer->zoomRectIndex() == 0) {
     
    236301
    237302//
    238 // Drag and drop methode
    239 //
    240 
    241 void FCS_Plot::dragEnterEvent(QDragEnterEvent *Event) {
     303// Drag and drop methods
     304//
     305
     306void Edd_Plot::dragEnterEvent(QDragEnterEvent *Event) {
    242307   
    243308  if (Event->mimeData()->hasFormat("text/plain")) Event->acceptProposedAction();
    244309}
    245310
    246 void FCS_Plot::dropEvent(QDropEvent *Event) {
    247 
    248  FCS_Plot *Graph = new FCS_Plot(Event->mimeData()->text().toAscii().data(), NULL);
    249  Graph->show();
     311void Edd_Plot::dropEvent(QDropEvent *Event) {
     312
     313  AddService(Event->mimeData()->text().toAscii().data());
    250314}
    251315   
     
    253317// Context menu and its functions
    254318//
    255 void FCS_Plot::contextMenuEvent(QContextMenuEvent *Event) {
     319void Edd_Plot::contextMenuEvent(QContextMenuEvent *Event) {
    256320
    257321  Menu->exec(Event->globalPos());
    258322}
    259323
    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() {
     324void Edd_Plot::MenuZoomOut() {
    270325
    271326  Zoomer->zoom(0);
     
    273328}
    274329
    275 void FCS_Plot::MenuPrint() {
     330void 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
     344void Edd_Plot::MenuPrint() {
    276345
    277346  QPrinter *Printer = new QPrinter;
     
    285354}
    286355
    287 void FCS_Plot::MenuSave() {
     356void Edd_Plot::MenuSave() {
    288357
    289358  QString Filename = QFileDialog::getSaveFileName(this,
     
    309378 
    310379   // 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);
    316385
    317386  // Clock (updated every second)
     
    345414    char *Item;
    346415    if (asprintf(&Item, "BIAS/VOLT/ID00/00-%.3d", i) != -1) {
    347       Value = new FCS_Indicator(Item, NULL);
     416      Value = new Edd_Indicator(Item, NULL);
    348417      BiasLayout->addWidget(Value, i%10, 0+i/10, 1, 1);     
    349418      free(Item);
    350419    }
    351420    if (asprintf(&Item, "BIAS/VOLT/ID00/01-%.3d", i) != -1) {
    352       Value = new FCS_Indicator(Item, NULL);
     421      Value = new Edd_Indicator(Item, NULL);
    353422      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);     
    354434      free(Item);
    355435    }
     
    360440  TabWidget->addTab(MainWidget, "&Main");
    361441  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);
    363450
    364451   
    365 
    366452GUI::~GUI() {
    367453  delete Central;
    368454}
    369455
     456void 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}
    370466
    371467//---------------------------------------------------------------------
  • Evidence/Edd/Edd.h

    • Property svn:keywords set to Revision
    r136 r138  
     1#ifndef EDD_H_SEEN
     2#define EDD_H_SEEN
     3
    14#include <QtGui>
    2 
     5 
    36#include <qwt_plot.h>
    47#include <qwt_plot_curve.h>
     
    1013#include <qwt_scale_widget.h>
    1114#include <qwt_plot_layout.h>
     15#include <qwt_legend.h>
     16#include <qwt_legend_item.h>
    1217
    1318#include <limits.h>
     
    1823
    1924#define NO_LINK "__&DIM&NOLINK&__" // for checking if DIMserver is alive
    20 
     25#define SVN_REVISION "$Revision$"
     26                 
    2127// General indicator for DIM service
    22 class FCS_Indicator: public QLineEdit, public DimClient, public DimBrowser {
     28class Edd_Indicator: public QLineEdit, public DimClient, public DimBrowser {
    2329    Q_OBJECT
    2430
     
    3440       
    3541  public:
    36     FCS_Indicator(char*, QWidget* = NULL);
    37     ~FCS_Indicator();
     42    Edd_Indicator(char*, QWidget* = NULL);
     43    ~Edd_Indicator();
    3844
    3945  signals:
     
    4248
    4349// Graph class for history display
    44 class FCS_Plot: public QwtPlot, public DimClient {
     50class Edd_Plot: public QwtPlot, public DimClient {
    4551    Q_OBJECT
    4652
    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    };
    5062
     63    QList<struct PlotItem> Items;
     64    QMutex Mutex;
     65   
    5166    QMenu *Menu;
    5267    QAction *YLogAction;
     
    5570    QwtPlotPanner *Panner;
    5671    QwtPlotGrid *Grid;
    57     QwtPlotCurve *Signal;
    5872    QwtPlotZoomer *Zoomer;
    59 
     73    QwtLegend *Legend;
     74   
     75    void AddService(char *);
     76    void infoHandler();   
    6077    void dragEnterEvent(QDragEnterEvent *);
    6178    void dropEvent(QDropEvent *);
    6279
    6380  public:
    64     FCS_Plot(char*, QWidget* = NULL);
    65     ~FCS_Plot();
     81    Edd_Plot(char *, QWidget * = NULL);
     82    ~Edd_Plot();
    6683
    67   private slots:   
     84  private slots:
     85    void UpdatePlot();
    6886    void HandleZoom(const QwtDoubleRect &);
    6987    void contextMenuEvent(QContextMenuEvent *);   
    70     void MenuYScale();
    7188    void MenuZoomOut();
     89    void MenuSingleTrace();       
    7290    void MenuSave();
    7391    void MenuPrint();
     
    82100    Q_OBJECT
    83101
    84     FCS_Indicator *Value, *Value1;
    85     FCS_Plot *Graph, *Graph1;
     102    Edd_Indicator *Value, *Value1;
     103    Edd_Plot *Graph, *Graph1;
    86104    QwtAnalogClock *Clock;
    87105       
    88     QWidget *Central, *MainWidget, *BiasWidget;
    89     QGridLayout *MainLayout, *BiasLayout;
     106    QWidget *Central, *MainWidget, *BiasWidget, *EnvironmentWidget;
     107    QGridLayout *MainLayout, *BiasLayout, *EnvironmentLayout;
    90108
    91109    QTabWidget *TabWidget;
    92110           
    93111    void closeEvent(QCloseEvent *);
    94          
     112
    95113  public:
    96114    GUI();
    97115    ~GUI();
     116   
     117  private slots:
     118    void MenuAbout();
    98119};
     120
     121#endif
Note: See TracChangeset for help on using the changeset viewer.