├── AVNSignalAnalyser_win32.rc ├── AVNUtilLibs └── .directory ├── Images ├── AVNLogo.ico ├── AVNLogo.png └── SKALogo.png ├── .gitignore ├── Images.qrc ├── README.md ├── Main.cpp ├── AboutDialog.h ├── .gitmodules ├── MainWindow.h ├── AboutDialog.cpp ├── NetworkConnectionWidget.h ├── PlotsWidget.ui ├── NetworkConnectionWidget.cpp ├── MainWindow.cpp ├── AVNSignalAnalyser.pro ├── MainWindow.ui ├── PlotsWidget.h ├── NetworkConnectionWidget.ui ├── RoachAcquisitionServerKATCPClient.h ├── RoachAcquistionControlWidget.h ├── AboutDialog.ui ├── PlotsWidget.cpp ├── RoachAcquisitionServerKATCPClient.cpp └── RoachAcquistionControlWidget.cpp /AVNSignalAnalyser_win32.rc: -------------------------------------------------------------------------------- 1 | IDI_ICON1 ICON DISCARDABLE "Images/AVNLogo.ico" -------------------------------------------------------------------------------- /AVNUtilLibs/.directory: -------------------------------------------------------------------------------- 1 | [Dolphin] 2 | Timestamp=2015,8,14,15,52,4 3 | Version=3 4 | ViewMode=1 5 | -------------------------------------------------------------------------------- /Images/AVNLogo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/AVNSignalAnalyser/master/Images/AVNLogo.ico -------------------------------------------------------------------------------- /Images/AVNLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/AVNSignalAnalyser/master/Images/AVNLogo.png -------------------------------------------------------------------------------- /Images/SKALogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ska-sa/AVNSignalAnalyser/master/Images/SKALogo.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | AVNSignalAnalyser.pro.* 2 | AVNSignalAnalyser 3 | AVNSignalAnalyser.exe 4 | *.o 5 | *.moc 6 | Makefile 7 | ui_* 8 | -------------------------------------------------------------------------------- /Images.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | Images/AVNLogo.ico 4 | Images/AVNLogo.png 5 | Images/SKALogo.png 6 | 7 | 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Deprecated 2 | 3 | This software was developed initially by Craig Tong for use in AVN Ghana. 4 | It is a QT desktop application which connects to a running single-dish 5 | backend and allows controlling the ROACH, recording data files, etc. as 6 | well as real-time visibility into what the RF signal-chain is doing. 7 | 8 | The functionality has largely been superceded by the CAM system for AVN 9 | Ghana. This repo is therefore retained only for historical purposes. 10 | -------------------------------------------------------------------------------- /Main.cpp: -------------------------------------------------------------------------------- 1 | //System includes 2 | 3 | //Library includes 4 | 5 | //Local includes 6 | #include "MainWindow.h" 7 | #include 8 | 9 | int main(int argc, char *argv[]) 10 | { 11 | QApplication a(argc, argv); 12 | 13 | a.setApplicationName("AVNSignalAnalyser"); 14 | a.setApplicationVersion("0.0.3"); 15 | a.setOrganizationName("SKA SA"); 16 | a.setOrganizationDomain("ska.ac.za"); 17 | 18 | cMainWindow w; 19 | w.show(); 20 | 21 | return a.exec(); 22 | } 23 | -------------------------------------------------------------------------------- /AboutDialog.h: -------------------------------------------------------------------------------- 1 | //******************************************** 2 | //## Commensal Radar Project ## 3 | // 4 | //Filename: 5 | // AboutDialog.h 6 | // 7 | //Description: 8 | // This class displays an about dialog for the ARDView app. 9 | // 10 | //Author: 11 | // Craig Tong 12 | // Radar Remote Sensing Group 13 | // Department of Electrical Engineering 14 | // University of Cape Town 15 | // craig.tong@uct.ac.za 16 | // Copyright © 2013 Craig Tong 17 | //******************************************** 18 | 19 | #ifndef ABOUTDIALOG_H 20 | #define ABOUTDIALOG_H 21 | 22 | #include 23 | #include "ui_AboutDialog.h" 24 | 25 | //This class displays an about dialog for the ARDView app. 26 | 27 | class cAboutDialog : public QDialog 28 | { 29 | public: 30 | cAboutDialog(QWidget*); 31 | ~cAboutDialog(); 32 | 33 | private: 34 | Ui_AboutDialog* m_pADialog; 35 | }; 36 | 37 | #endif // ABOUTDIALOG_H 38 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "AVNUtilLibs/Sockets"] 2 | path = AVNUtilLibs/Sockets 3 | url = https://github.com/ska-sa/AVNSockets.git 4 | [submodule "AVNUtilLibs/DataStructures"] 5 | path = AVNUtilLibs/DataStructures 6 | url = https://github.com/ska-sa/AVNDataStructures.git 7 | [submodule "AVNAppLibs/SocketStreamers"] 8 | path = AVNAppLibs/SocketStreamers 9 | url = https://github.com/ska-sa/AVNSocketStreamers.git 10 | [submodule "AVNUtilLibs/Timestamp"] 11 | path = AVNUtilLibs/Timestamp 12 | url = https://github.com/ska-sa/AVNTimestamp.git 13 | [submodule "AVNDataTypes/SpectrometerDataStream"] 14 | path = AVNDataTypes/SpectrometerDataStream 15 | url = https://github.com/ska-sa/AVNSpectrometerDataStream.git 16 | [submodule "AVNGUILibs/QwtPlotting"] 17 | path = AVNGUILibs/QwtPlotting 18 | url = https://github.com/ska-sa/AVNQwtPlotting.git 19 | [submodule "AVNAppLibs/KATCP"] 20 | path = AVNAppLibs/KATCP 21 | url = https://github.com/ska-sa/AVNKATCP.git 22 | -------------------------------------------------------------------------------- /MainWindow.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_H 2 | #define MAINWINDOW_H 3 | 4 | //System includes 5 | 6 | //Library includes 7 | #include 8 | #include 9 | #include 10 | 11 | //Local includes 12 | #include "NetworkConnectionWidget.h" 13 | #include "PlotsWidget.h" 14 | #include "RoachAcquistionControlWidget.h" 15 | 16 | namespace Ui { 17 | class cMainWindow; 18 | } 19 | 20 | class cMainWindow : public QMainWindow 21 | { 22 | Q_OBJECT 23 | 24 | public: 25 | explicit cMainWindow(QWidget *pParent = 0); 26 | ~cMainWindow(); 27 | 28 | private: 29 | Ui::cMainWindow *m_pUI; 30 | cNetworkConnectionWidget *m_pNetworkGroupBox; 31 | cPlotsWidget *m_pPlotsWidget; 32 | QScopedPointer m_pAquisitionWidget; 33 | 34 | void connectSignalsToSlots(); 35 | 36 | void closeEvent(QCloseEvent *pEvent); //Overload to close RoachAcquisitionControlDialog if it is open before closing main window 37 | 38 | private slots: 39 | void slotSetConnectedOrBound(bool bIsConnectedOrBound); 40 | void slotKATCPEnabled(bool bEnabled); 41 | void slotSetKATCPConnected(bool bIsKATCPConnected); 42 | void slotOpenAboutDialog(); 43 | }; 44 | 45 | #endif // MAINWINDOW_H 46 | -------------------------------------------------------------------------------- /AboutDialog.cpp: -------------------------------------------------------------------------------- 1 | //******************************************** 2 | //## Commensal Radar Project ## 3 | // 4 | //Filename: 5 | // AboutDialog.h 6 | // 7 | //Description: 8 | // This class displays an about dialog for the ARDView app. 9 | // 10 | //Author: 11 | // Craig Tong 12 | // Radar Remote Sensing Group 13 | // Department of Electrical Engineering 14 | // University of Cape Town 15 | // craig.tong@uct.ac.za 16 | // Copyright © 2013 Craig Tong 17 | //******************************************** 18 | 19 | #include "AboutDialog.h" 20 | #include 21 | 22 | cAboutDialog::cAboutDialog(QWidget *parent) : QDialog(parent, Qt::Dialog) 23 | { 24 | m_pADialog = new Ui_AboutDialog(); 25 | m_pADialog->setupUi(this); 26 | m_pADialog->label_version->setText(QString("Version: %1").arg(QCoreApplication::applicationVersion())); 27 | 28 | 29 | #ifdef _WIN32 30 | #ifdef _WIN64 31 | m_pADialog->label_platform->setText(QString("Platform: MSVC Win64")); 32 | #else 33 | m_pADialog->label_platform->setText(QString("Platform: MSVC Win32")); 34 | #endif 35 | #else 36 | #ifdef __unix__ 37 | #ifdef __x86_64__ 38 | m_pADialog->label_platform->setText(QString("Platform: GCC x86_64")); 39 | #else 40 | m_pADialog->label_platform->setText(QString("Platform: GCC x86")); 41 | #endif 42 | #else 43 | #ifdef __MAC__ 44 | m_pADialog->label_platform->setText(QString("Platform: Mac")); 45 | #else 46 | m_pADialog->label_platform->setText(QString("Platform: Unknown")); 47 | #endif 48 | #endif 49 | #endif 50 | 51 | m_pADialog->label_buildDate->setText(QString("Build date: %1 %2").arg(__DATE__).arg(__TIME__)); 52 | m_pADialog->label_year->setText(QString("Copyright %1 2015 SKA SA. All rights reserved").arg(QString::fromUtf8("©"))); 53 | } 54 | 55 | cAboutDialog::~cAboutDialog() 56 | { 57 | delete m_pADialog; 58 | } 59 | -------------------------------------------------------------------------------- /NetworkConnectionWidget.h: -------------------------------------------------------------------------------- 1 | #ifndef NETWORK_CONNECTION_WIDGET_H 2 | #define NETWORK_CONNECTION_WIDGET_H 3 | 4 | //System includes 5 | #ifdef _WIN32 6 | #include 7 | #else 8 | #include 9 | #endif 10 | 11 | //Library includes 12 | #include 13 | 14 | //Local includes 15 | 16 | 17 | namespace Ui { 18 | class cNetworkConnectionWidget; 19 | } 20 | 21 | class cNetworkConnectionWidget : public QGroupBox 22 | { 23 | Q_OBJECT 24 | 25 | public: 26 | enum dataProtocol 27 | { 28 | TCP=0, 29 | UDP 30 | }; 31 | 32 | explicit cNetworkConnectionWidget(bool bTCPAvailable = true, bool bUDPAvailable = true, bool bKATCPAvailable = true, QWidget *pParent = 0); 33 | ~cNetworkConnectionWidget(); 34 | 35 | void setTCPAvailable(bool bAvailable); 36 | void setUDPAvailable(bool bAvailable); 37 | void setKATCPAvailable(bool bAvailable); 38 | 39 | QString getPeerAddress() const; 40 | uint16_t getDataPort() const; 41 | uint16_t getKATCPPort() const; 42 | 43 | private: 44 | Ui::cNetworkConnectionWidget *m_pUI; 45 | 46 | dataProtocol m_eDataProtocol; 47 | bool m_bIsConnectedOrBound; 48 | bool m_bTCPIsAvailable; 49 | bool m_bUDPIsAvailable; 50 | bool m_bKATCPAvailable; 51 | 52 | void connectSignalsToSlots(); 53 | void updateAvailableProtocols(); 54 | void updateGUI(); 55 | 56 | private slots: 57 | void slotSetDataProtocol(int iDataProtocol); 58 | void slotKATCPEnabled(bool bEnabled); 59 | 60 | public slots: 61 | void slotSetConnectedOrBound(bool bIsConnectedOrBound); 62 | void slotConnectDisconnect(); 63 | 64 | signals: 65 | void sigConnectClicked(int iDataProtocol, const QString &qstrLocalInterface, unsigned short usLocalPort, const QString &qstrPeerAddress, unsigned short usPort); 66 | void sigDisconnectClicked(); 67 | void sigConnectedOrBound(bool); 68 | void sigConnectKATCP(bool bConnect); 69 | 70 | }; 71 | 72 | #endif // NETWORK_CONNECTION_WIDGET_H 73 | -------------------------------------------------------------------------------- /PlotsWidget.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | cPlotsWidget 4 | 5 | 6 | 7 | 0 8 | 0 9 | 836 10 | 509 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 2 19 | 20 | 21 | 0 22 | 23 | 24 | 25 | 26 | 27 | 0 28 | 0 29 | 30 | 31 | 32 | 33 | 8 34 | 35 | 36 | 37 | Powers 38 | 39 | 40 | Qt::AlignCenter 41 | 42 | 43 | true 44 | 45 | 46 | 47 | 0 48 | 49 | 50 | 0 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 0 60 | 0 61 | 62 | 63 | 64 | 65 | 8 66 | 67 | 68 | 69 | Stokes 70 | 71 | 72 | Qt::AlignCenter 73 | 74 | 75 | true 76 | 77 | 78 | 79 | 0 80 | 81 | 82 | 0 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 0 92 | 0 93 | 94 | 95 | 96 | 97 | 8 98 | 99 | 100 | 101 | Band Power 102 | 103 | 104 | Qt::AlignCenter 105 | 106 | 107 | true 108 | 109 | 110 | 111 | 0 112 | 113 | 114 | 0 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /NetworkConnectionWidget.cpp: -------------------------------------------------------------------------------- 1 | //System includes 2 | 3 | //Library includes 4 | #include 5 | 6 | //Local includes 7 | #include "NetworkConnectionWidget.h" 8 | #include "ui_NetworkConnectionWidget.h" 9 | 10 | cNetworkConnectionWidget::cNetworkConnectionWidget(bool bTCPAvailable, bool bUDPAvailable, bool bKATCPAvailable, QWidget *pParent) : 11 | QGroupBox(pParent), 12 | m_pUI(new Ui::cNetworkConnectionWidget), 13 | m_bIsConnectedOrBound(false), 14 | m_bTCPIsAvailable(bTCPAvailable), 15 | m_bUDPIsAvailable(bUDPAvailable), 16 | m_bKATCPAvailable(bKATCPAvailable) 17 | { 18 | m_pUI->setupUi(this); 19 | 20 | connectSignalsToSlots(); 21 | 22 | updateAvailableProtocols(); 23 | updateGUI(); 24 | } 25 | 26 | cNetworkConnectionWidget::~cNetworkConnectionWidget() 27 | { 28 | delete m_pUI; 29 | } 30 | 31 | void cNetworkConnectionWidget::connectSignalsToSlots() 32 | { 33 | QObject::connect( m_pUI->comboBox_dataProtocol, SIGNAL(currentIndexChanged(int)), this, SLOT(slotSetDataProtocol(int)) ); 34 | QObject::connect( m_pUI->pushButton_connectDisconnect, SIGNAL(clicked()), this, SLOT(slotConnectDisconnect()) ); 35 | QObject::connect( m_pUI->checkBox_KATCPControl, SIGNAL(toggled(bool)), this, SLOT(slotKATCPEnabled(bool)) ); 36 | } 37 | 38 | void cNetworkConnectionWidget::slotSetDataProtocol(int iDataProtocol) 39 | { 40 | m_eDataProtocol = dataProtocol(iDataProtocol); 41 | updateGUI(); 42 | } 43 | 44 | void cNetworkConnectionWidget::slotConnectDisconnect() 45 | { 46 | if(m_bIsConnectedOrBound) 47 | { 48 | sigDisconnectClicked(); 49 | sigConnectKATCP(false); 50 | } 51 | else 52 | { 53 | switch(m_eDataProtocol) 54 | { 55 | case TCP: 56 | sigConnectClicked(TCP, QString(""), 0, m_pUI->lineEdit_server->text(), (unsigned short)m_pUI->spinBox_serverPort->value()); 57 | break; 58 | 59 | case UDP: 60 | sigConnectClicked(UDP, m_pUI->lineEdit_interface->text(), m_pUI->spinBox_localPort->value(), m_pUI->lineEdit_server->text(), (unsigned short)m_pUI->spinBox_serverPort->value()); 61 | break; 62 | 63 | default: 64 | return; //Shouldn't ever be reached if the GUI is correct 65 | } 66 | 67 | if(m_pUI->checkBox_KATCPControl->isChecked()) 68 | { 69 | sigConnectKATCP(true); 70 | } 71 | } 72 | } 73 | 74 | void cNetworkConnectionWidget::slotSetConnectedOrBound(bool bIsConnectedOrBound) 75 | { 76 | m_bIsConnectedOrBound = bIsConnectedOrBound; 77 | 78 | updateGUI(); 79 | 80 | sigConnectedOrBound(m_bIsConnectedOrBound); 81 | } 82 | 83 | void cNetworkConnectionWidget::updateGUI() 84 | { 85 | if(m_pUI->comboBox_dataProtocol->currentText() == QString("TCP")) 86 | { 87 | if(m_bIsConnectedOrBound) 88 | { 89 | m_pUI->pushButton_connectDisconnect->setText(QString("Disconnect")); 90 | } 91 | else 92 | { 93 | m_pUI->pushButton_connectDisconnect->setText(QString("Connect")); 94 | } 95 | 96 | m_pUI->label_interface->setVisible(false); 97 | m_pUI->lineEdit_interface->setVisible(false); 98 | m_pUI->spinBox_localPort->setVisible(false); 99 | m_pUI->label_localColon->setVisible(false); 100 | } 101 | else 102 | { 103 | if(m_bIsConnectedOrBound) 104 | { 105 | m_pUI->pushButton_connectDisconnect->setText(QString("Unbind")); 106 | } 107 | else 108 | { 109 | m_pUI->pushButton_connectDisconnect->setText(QString("Bind")); 110 | } 111 | 112 | m_pUI->label_interface->setVisible(true); 113 | m_pUI->lineEdit_interface->setVisible(true); 114 | m_pUI->spinBox_localPort->setVisible(true); 115 | m_pUI->label_localColon->setVisible(true); 116 | } 117 | 118 | } 119 | 120 | void cNetworkConnectionWidget::setTCPAvailable(bool bAvailable) 121 | { 122 | m_bTCPIsAvailable = bAvailable; 123 | updateAvailableProtocols(); 124 | } 125 | 126 | void cNetworkConnectionWidget::setUDPAvailable(bool bAvailable) 127 | { 128 | m_bUDPIsAvailable = bAvailable; 129 | updateAvailableProtocols(); 130 | } 131 | 132 | void cNetworkConnectionWidget::setKATCPAvailable(bool bAvailable) 133 | { 134 | m_bUDPIsAvailable = bAvailable; 135 | updateAvailableProtocols(); 136 | } 137 | 138 | void cNetworkConnectionWidget::updateAvailableProtocols() 139 | { 140 | m_pUI->comboBox_dataProtocol->clear(); 141 | 142 | if(m_bTCPIsAvailable) 143 | { 144 | m_pUI->comboBox_dataProtocol->addItem(QString("TCP")); 145 | } 146 | 147 | if(m_bUDPIsAvailable) 148 | { 149 | m_pUI->comboBox_dataProtocol->addItem(QString("UDP")); 150 | } 151 | } 152 | 153 | void cNetworkConnectionWidget::slotKATCPEnabled(bool bEnabled) 154 | { 155 | if(m_bIsConnectedOrBound) 156 | { 157 | sigConnectKATCP(bEnabled); //Relay as signal from the NetworkConnectionWidget 158 | } 159 | } 160 | 161 | QString cNetworkConnectionWidget::getPeerAddress() const 162 | { 163 | return m_pUI->lineEdit_server->text(); 164 | } 165 | 166 | uint16_t cNetworkConnectionWidget::getDataPort() const 167 | { 168 | return m_pUI->spinBox_serverPort->value(); 169 | } 170 | 171 | uint16_t cNetworkConnectionWidget::getKATCPPort() const 172 | { 173 | return m_pUI->spinBox_KATCPPort->value(); 174 | } 175 | -------------------------------------------------------------------------------- /MainWindow.cpp: -------------------------------------------------------------------------------- 1 | //System includes 2 | #include 3 | 4 | //Library includes 5 | #include 6 | 7 | //Local includes 8 | #include "MainWindow.h" 9 | #include "ui_MainWindow.h" 10 | #include "AboutDialog.h" 11 | 12 | using namespace std; 13 | 14 | cMainWindow::cMainWindow(QWidget *pParent) : 15 | QMainWindow(pParent), 16 | m_pUI(new Ui::cMainWindow), 17 | m_pNetworkGroupBox(new cNetworkConnectionWidget(true, true, this)), //No UDP currently 18 | m_pPlotsWidget(new cPlotsWidget(this)) 19 | { 20 | m_pUI->setupUi(this); 21 | qApp->installEventFilter( this ); 22 | 23 | m_pUI->horizontalLayout_MainWindowTop->insertSpacerItem(1, new QSpacerItem(20, 20, QSizePolicy::MinimumExpanding, QSizePolicy::Fixed)); 24 | m_pUI->horizontalLayout_MainWindowTop->insertWidget(2, m_pNetworkGroupBox); 25 | m_pUI->verticalLayout_mainWindow->insertWidget(1, m_pPlotsWidget); 26 | 27 | connectSignalsToSlots(); 28 | 29 | cout << "cMainWindow::cMainWindow() Thread is: " << QThread::currentThread() << endl; 30 | } 31 | 32 | cMainWindow::~cMainWindow() 33 | { 34 | slotKATCPEnabled(false); 35 | delete m_pUI; 36 | } 37 | 38 | void cMainWindow::connectSignalsToSlots() 39 | { 40 | //NetworkGroupBox controls 41 | QObject::connect( m_pNetworkGroupBox, SIGNAL(sigConnectClicked(int, const QString&, unsigned short, const QString&, unsigned short)), 42 | m_pPlotsWidget, SLOT(slotConnect(int, const QString&, unsigned short, const QString&, unsigned short)) ); 43 | QObject::connect( m_pNetworkGroupBox, SIGNAL(sigDisconnectClicked()), m_pPlotsWidget, SLOT(slotDisconnect()) ); 44 | QObject::connect( m_pPlotsWidget, SIGNAL(sigConnected(bool)), m_pNetworkGroupBox, SLOT(slotSetConnectedOrBound(bool)) ); 45 | QObject::connect( m_pNetworkGroupBox, SIGNAL(sigConnectedOrBound(bool)), this, SLOT(slotSetConnectedOrBound(bool)) ); 46 | QObject::connect( m_pNetworkGroupBox, SIGNAL(sigConnectKATCP(bool)), this, SLOT(slotKATCPEnabled(bool)) ); 47 | 48 | //File menu actions 49 | QObject::connect( m_pUI->actionExit, SIGNAL(triggered()), this, SLOT(close())); 50 | 51 | //Server menu actions 52 | QObject::connect( m_pUI->actionConnect_Bind, SIGNAL(triggered()), m_pNetworkGroupBox, SLOT(slotConnectDisconnect())); 53 | QObject::connect( m_pUI->actionDisconnect_Unbind, SIGNAL(triggered()), m_pNetworkGroupBox, SLOT(slotConnectDisconnect())); 54 | 55 | //Help menu actions 56 | QObject::connect( m_pUI->actionAbout, SIGNAL ( triggered()), this, SLOT ( slotOpenAboutDialog() ) ); 57 | 58 | //Plots menu actions 59 | //Menu notifying PlotsWidget 60 | QObject::connect( m_pUI->actionShowChannelPowers, SIGNAL ( triggered(bool) ), m_pPlotsWidget, SLOT ( slotEnablePowerPlot(bool) ) ); 61 | QObject::connect( m_pUI->actionShowStokesPhase, SIGNAL ( triggered(bool) ), m_pPlotsWidget, SLOT ( slotEnableStokesPhasePlot(bool) ) ); 62 | QObject::connect( m_pUI->actionShowBandPowers, SIGNAL ( triggered(bool) ), m_pPlotsWidget, SLOT ( slotEnableBandPowerPlot(bool) ) ); 63 | //PlotsWidget notifying menu 64 | QObject::connect( m_pPlotsWidget, SIGNAL ( sigPowerPlotEnabled(bool) ), m_pUI->actionShowChannelPowers, SLOT ( setChecked(bool) ) ); 65 | QObject::connect( m_pPlotsWidget, SIGNAL ( sigStokesPhasePlotEnabled(bool) ), m_pUI->actionShowStokesPhase, SLOT ( setChecked(bool) ) ); 66 | QObject::connect( m_pPlotsWidget, SIGNAL ( sigBandPowerPlotEnabled(bool) ), m_pUI->actionShowBandPowers, SLOT ( setChecked(bool) ) ); 67 | } 68 | 69 | void cMainWindow::slotSetConnectedOrBound(bool bIsConnectedOrBound) 70 | { 71 | //Update menu entries 72 | m_pUI->actionConnect_Bind->setEnabled(!bIsConnectedOrBound); 73 | m_pUI->actionDisconnect_Unbind->setEnabled(bIsConnectedOrBound); 74 | } 75 | 76 | void cMainWindow::slotKATCPEnabled(bool bEnabled) 77 | { 78 | if(bEnabled) 79 | { 80 | cout << "cMainWindow::slotKATCPEnabled() Starting KATCP client" << endl; 81 | 82 | m_pAquisitionWidget.reset( new cRoachAcquistionControlWidget(m_pPlotsWidget)); 83 | m_pAquisitionWidget->setModal(false); //Don't block the rest of the GUI and don't be always-on-top 84 | 85 | QObject::connect( m_pUI->actionOpen_Roach_Aquisition_Control_Dialogue, SIGNAL(triggered()), m_pAquisitionWidget.data(), SLOT(show()) ); 86 | 87 | if(!m_pAquisitionWidget->connect(m_pNetworkGroupBox->getPeerAddress(), m_pNetworkGroupBox->getKATCPPort())) 88 | { 89 | cout << "cMainWindow::slotKATCPEnabled() KATCP connection failed..." << endl; 90 | slotKATCPEnabled(false); 91 | return; 92 | } 93 | 94 | m_pUI->actionOpen_Roach_Aquisition_Control_Dialogue->setEnabled(true); 95 | m_pAquisitionWidget->show(); 96 | 97 | cout << "cMainWindow::slotKATCPEnabled() KATCP client started..." << endl; 98 | } 99 | else 100 | { 101 | cout << "cMainWindow::slotKATCPEnabled() Stopping KATCP client" << endl; 102 | 103 | QObject::disconnect( m_pUI->actionOpen_Roach_Aquisition_Control_Dialogue, SIGNAL(triggered()), m_pAquisitionWidget.data(), SLOT(show()) ); 104 | m_pUI->actionOpen_Roach_Aquisition_Control_Dialogue->setEnabled(false); 105 | m_pAquisitionWidget.reset(); 106 | 107 | cout << "cMainWindow::slotKATCPEnabled() KATCP client terminated..." << endl; 108 | } 109 | } 110 | 111 | void cMainWindow::slotSetKATCPConnected(bool bIsKATCPConnected) 112 | { 113 | //Update menu entry 114 | 115 | 116 | if(bIsKATCPConnected) 117 | m_pAquisitionWidget->show(); 118 | } 119 | 120 | void cMainWindow::slotOpenAboutDialog() 121 | { 122 | cAboutDialog oAboutDialog(this); 123 | oAboutDialog.layout()->setSizeConstraint( QLayout::SetFixedSize ); 124 | oAboutDialog.show(); 125 | oAboutDialog.exec(); 126 | } 127 | 128 | void cMainWindow::closeEvent(QCloseEvent *pEvent) 129 | { 130 | //Intercept close event and close the KATCP dialog 131 | slotKATCPEnabled(false); 132 | 133 | //Then process the event as normal 134 | QMainWindow::closeEvent(pEvent); 135 | } 136 | -------------------------------------------------------------------------------- /AVNSignalAnalyser.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2015-07-03T10:48:57 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | 9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 10 | 11 | TARGET = AVNSignalAnalyser 12 | TEMPLATE = app 13 | 14 | DEFINES += USE_BOOST_TIME=1 #Use boost libs for timestamp derivation 15 | 16 | SOURCES +=\ 17 | MainWindow.cpp \ 18 | Main.cpp \ 19 | AVNUtilLibs/Sockets/InterruptibleBlockingSockets/InterruptibleBlockingTCPSocket.cpp \ 20 | AVNUtilLibs/Sockets/InterruptibleBlockingSockets/InterruptibleBlockingUDPSocket.cpp \ 21 | AVNAppLibs/SocketStreamers/TCPReceiver/TCPReceiver.cpp \ 22 | PlotsWidget.cpp \ 23 | AVNDataTypes/SpectrometerDataStream/SpectrometerHeader.cpp \ 24 | AVNGUILibs/QwtPlotting/BasicQwtLinePlotWidget.cpp \ 25 | AVNGUILibs/QwtPlotting/FramedQwtLinePlotWidget.cpp \ 26 | AVNGUILibs/QwtPlotting/ScrollingQwtLinePlotWidget.cpp \ 27 | AVNGUILibs/QwtPlotting/BandPowerQwtLinePlotWidget.cpp \ 28 | AVNGUILibs/QwtPlotting/CursorCentredQwtPlotMagnifier.cpp \ 29 | AVNGUILibs/QwtPlotting/AnimatedQwtPlotZoomer.cpp \ 30 | AVNAppLibs/SocketStreamers/SocketReceiverBase.cpp \ 31 | AVNAppLibs/SocketStreamers/UDPReceiver/UDPReceiver.cpp \ 32 | NetworkConnectionWidget.cpp \ 33 | AVNDataTypes/SpectrometerDataStream/SpectrometerDataStreamInterpreter.cpp \ 34 | AVNUtilLibs/Timestamp/Timestamp.cpp \ 35 | AVNDataTypes/SpectrometerDataStream/SpectrometerDefinitions.cpp \ 36 | AboutDialog.cpp \ 37 | AVNGUILibs/QwtPlotting/WaterfallQwtPlotWidget.cpp \ 38 | AVNGUILibs/QwtPlotting/WaterfallPlotSpectromgramData.cpp \ 39 | AVNGUILibs/QwtPlotting/WallTimeQwtScaleDraw.cpp \ 40 | AVNGUILibs/QwtPlotting/QwtPlotDistancePicker.cpp \ 41 | AVNGUILibs/QwtPlotting/QwtPlotWidgetBase.cpp \ 42 | AVNGUILibs/QwtPlotting/QwtPlotPositionPicker.cpp \ 43 | AVNAppLibs/KATCP/KATCPClientBase.cpp \ 44 | RoachAcquisitionServerKATCPClient.cpp \ 45 | AVNDataTypes/SpectrometerDataStream/cSpectrometerOverflowRegisters.cpp \ 46 | RoachAcquistionControlWidget.cpp 47 | 48 | HEADERS += MainWindow.h \ 49 | AVNUtilLibs/DataStructures/ThreadSafeCircularBuffer/ThreadSafeCircularBuffer.h \ 50 | AVNUtilLibs/Sockets/InterruptibleBlockingSockets/InterruptibleBlockingTCPSocket.h \ 51 | AVNUtilLibs/Sockets/InterruptibleBlockingSockets/InterruptibleBlockingUDPSocket.h \ 52 | AVNAppLibs/SocketStreamers/TCPReceiver/TCPReceiver.h \ 53 | PlotsWidget.h \ 54 | AVNDataTypes/SpectrometerDataStream/SpectrometerDefinitions.h \ 55 | AVNDataTypes/SpectrometerDataStream/SpectrometerHeader.h \ 56 | AVNGUILibs/QwtPlotting/BasicQwtLinePlotWidget.h \ 57 | AVNGUILibs/QwtPlotting/FramedQwtLinePlotWidget.h \ 58 | AVNGUILibs/QwtPlotting/ScrollingQwtLinePlotWidget.h \ 59 | AVNGUILibs/QwtPlotting/BandPowerQwtLinePlotWidget.h \ 60 | AVNUtilLibs/Timestamp/Timestamp.h \ 61 | AVNGUILibs/QwtPlotting/CursorCentredQwtPlotMagnifier.h \ 62 | AVNGUILibs/QwtPlotting/AnimatedQwtPlotZoomer.h \ 63 | AVNAppLibs/SocketStreamers/SocketReceiverBase.h \ 64 | AVNAppLibs/SocketStreamers/UDPReceiver/UDPReceiver.h \ 65 | NetworkConnectionWidget.h \ 66 | AVNDataTypes/SpectrometerDataStream/SpectrometerDataStreamInterpreter.h \ 67 | AboutDialog.h \ 68 | AVNGUILibs/QwtPlotting/WaterfallQwtPlotWidget.h \ 69 | AVNGUILibs/QwtPlotting/WaterfallPlotSpectromgramData.h \ 70 | AVNGUILibs/QwtPlotting/WallTimeQwtScaleDraw.h \ 71 | AVNGUILibs/QwtPlotting/QwtPlotDistancePicker.h \ 72 | AVNGUILibs/QwtPlotting/QwtPlotPositionPicker.h \ 73 | AVNGUILibs/QwtPlotting/QwtPlotWidgetBase.h \ 74 | AVNAppLibs/KATCP/KATCPClientBase.h \ 75 | RoachAcquisitionServerKATCPClient.h \ 76 | AVNDataTypes/SpectrometerDataStream/cSpectrometerOverflowRegisters.h \ 77 | RoachAcquistionControlWidget.h 78 | 79 | 80 | FORMS += MainWindow.ui \ 81 | PlotsWidget.ui \ 82 | NetworkConnectionWidget.ui \ 83 | AboutDialog.ui \ 84 | AVNGUILibs/QwtPlotting/QwtPlotWidgetBase.ui \ 85 | RoachAcquistionControlWidget.ui 86 | 87 | RESOURCES += \ 88 | Images.qrc 89 | 90 | unix:!macx{ 91 | message(Detected Linux / Unix OS.) 92 | 93 | #Use Qt and Qwt from shared libs (For LGPL compliance) 94 | DEFINES += QT_DLL QWT_DLL 95 | 96 | #Distro specific library includes (caters for varying library names and paths) 97 | #Currently this is Qwt linking and includes 98 | SYSTEM_VERSION = $$system( cat /proc/version) 99 | message( "System version string: $$SYSTEM_VERSION" ) 100 | 101 | SYSTEM_GENTOO = $$system( cat /proc/version | grep -o Gentoo ) 102 | contains( SYSTEM_GENTOO, Gentoo ) { 103 | message( "Detected Gentoo Distribution." ) 104 | LIBS += -lqwt6 105 | INCLUDEPATH += /usr/include/qwt6 106 | } 107 | 108 | SYSTEM_UBUNTU = $$system( cat /proc/version | grep -o Ubuntu ) 109 | contains( SYSTEM_UBUNTU, Ubuntu ) { 110 | message( "Detected Ubuntu Distribution." ) 111 | LIBS += -lqwt 112 | INCLUDEPATH += /usr/include/qwt 113 | } 114 | 115 | SYSTEM_DEBIAN = $$system( cat /proc/version | grep -o Debian ) 116 | contains( SYSTEM_DEBIAN, Debian ) { 117 | message( "Detected Debian Distribution." ) 118 | LIBS += -lqwt 119 | INCLUDEPATH += /usr/include/qwt 120 | } 121 | 122 | #Boost seems to be ubiquitous across distros 123 | LIBS += -lboost_system -lboost_thread -lboost_chrono -lboost_date_time 124 | } 125 | 126 | macx{ 127 | message(Detected Mac OS.) 128 | 129 | #Use Qt and Qwt from shared libs (For LGPL compliance) 130 | DEFINES += QT_DLL QWT_DLL 131 | 132 | #Qwt 133 | LIBS += -lqwt 134 | INCLUDEPATH += /opt/local/libexec/qt4/include/qwt 135 | 136 | 137 | #Boost seems to be ubiquitous across distros 138 | INCLUDEPATH += /opt/local/include/ 139 | LIBS += -L/opt/local/lib -lboost_system-mt -lboost_thread-mt -lboost_chrono-mt -lboost_date_time-mt 140 | } 141 | 142 | win32{ 143 | message(Detected Windows OS.) 144 | 145 | #Use Qt and Qwt from shared libs (For LGPL compliance) 146 | DEFINES += QT_DLL QWT_DLL 147 | 148 | #Qwt 149 | LIBS += -LC://DevLibs//qwt-6.1.2//lib 150 | CONFIG(debug, debug|release) { 151 | LIBS += -lqwtd 152 | } else { 153 | LIBS += -lqwt 154 | } 155 | INCLUDEPATH += C://DevLibs//qwt-6.1.2//src 156 | 157 | #Boost 158 | CONFIG(debug, debug|release) { 159 | LIBS += -LC:\\DevLibs\\boost_1_59_0\\stage\\lib libboost_system-vc120-mt-gd-1_59.lib libboost_thread-vc120-mt-gd-1_59.lib libboost_chrono-vc120-mt-gd-1_59.lib libboost_date_time-vc120-mt-gd-1_59.lib 160 | } else { 161 | LIBS += -LC:\\DevLibs\\boost_1_59_0\\stage\\lib libboost_system-vc120-mt-1_59.lib libboost_thread-vc120-mt-1_59.lib libboost_chrono-vc120-mt-1_59.lib libboost_date_time-vc120-mt-1_59.lib 162 | } 163 | INCLUDEPATH += C:\\DevLibs\\boost_1_59_0 164 | 165 | #Winsock 166 | LIBS += Ws2_32.lib 167 | 168 | #Set application executable icon with this file: 169 | RC_FILE = AVNSignalAnalyser_win32.rc 170 | } 171 | -------------------------------------------------------------------------------- /MainWindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | cMainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 606 10 | 638 11 | 12 | 13 | 14 | 15 | 0 16 | 0 17 | 18 | 19 | 20 | AVN Signal Analyser 21 | 22 | 23 | 24 | :/Images/Images/AVNLogo.png:/Images/Images/AVNLogo.png 25 | 26 | 27 | 28 | 29 | 0 30 | 31 | 32 | 0 33 | 34 | 35 | 0 36 | 37 | 38 | 0 39 | 40 | 41 | 0 42 | 43 | 44 | 45 | 46 | 0 47 | 48 | 49 | 50 | 51 | 0 52 | 53 | 54 | 55 | 56 | 57 | 0 58 | 0 59 | 60 | 61 | 62 | 63 | 50 64 | 60 65 | 66 | 67 | 68 | 69 | 8 70 | 71 | 72 | 73 | 74 | 75 | 76 | :/Images/Images/SKALogo.png 77 | 78 | 79 | true 80 | 81 | 82 | Qt::AlignCenter 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 8 91 | 92 | 93 | 94 | Qt::Horizontal 95 | 96 | 97 | QSizePolicy::Fixed 98 | 99 | 100 | 101 | 6 102 | 20 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 0 112 | 0 113 | 114 | 115 | 116 | 117 | 64 118 | 60 119 | 120 | 121 | 122 | 123 | 8 124 | 125 | 126 | 127 | 128 | 129 | 130 | :/Images/Images/AVNLogo.png 131 | 132 | 133 | true 134 | 135 | 136 | Qt::AlignCenter 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 0 150 | 0 151 | 606 152 | 19 153 | 154 | 155 | 156 | 157 | File 158 | 159 | 160 | 161 | 162 | 163 | Help 164 | 165 | 166 | 167 | 168 | 169 | Plots 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | Server 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | TopToolBarArea 191 | 192 | 193 | false 194 | 195 | 196 | 197 | 198 | Open FFT (Ctrl + F) 199 | 200 | 201 | Ctrl+F 202 | 203 | 204 | 205 | 206 | Open Waterfall plot (Ctrl + W) 207 | 208 | 209 | 210 | 211 | Open integrated bandwidth plot (Ctrl + I) 212 | 213 | 214 | 215 | 216 | Exit (Alt + F4) 217 | 218 | 219 | 220 | 221 | About 222 | 223 | 224 | 225 | 226 | true 227 | 228 | 229 | true 230 | 231 | 232 | Show channel powers 233 | 234 | 235 | 236 | 237 | true 238 | 239 | 240 | true 241 | 242 | 243 | Show Stokes or relative phase 244 | 245 | 246 | 247 | 248 | true 249 | 250 | 251 | true 252 | 253 | 254 | Show band power history 255 | 256 | 257 | 258 | 259 | Connect / Bind 260 | 261 | 262 | 263 | 264 | false 265 | 266 | 267 | Disconnect / Unbind 268 | 269 | 270 | 271 | 272 | false 273 | 274 | 275 | Open Roach Aquisition Control Dialogue 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | -------------------------------------------------------------------------------- /PlotsWidget.h: -------------------------------------------------------------------------------- 1 | #ifndef PLOTSWIDGET_H 2 | #define PLOTSWIDGET_H 3 | 4 | //System includes 5 | 6 | //Library includes 7 | #include 8 | #include 9 | #include 10 | 11 | #ifndef Q_MOC_RUN //Qt's MOC and Boost have some issues don't let MOC process boost headers 12 | #include 13 | #endif 14 | 15 | //Local includes 16 | #include "AVNAppLibs/SocketStreamers/TCPReceiver/TCPReceiver.h" 17 | #include "AVNAppLibs/SocketStreamers/UDPReceiver/UDPReceiver.h" 18 | #include "AVNDataTypes/SpectrometerDataStream/SpectrometerDefinitions.h" 19 | #include "AVNDataTypes/SpectrometerDataStream/SpectrometerDataStreamInterpreter.h" 20 | #include "AVNGUILibs/QwtPlotting/FramedQwtLinePlotWidget.h" 21 | #include "AVNGUILibs/QwtPlotting/BandPowerQwtLinePlotWidget.h" 22 | #include "NetworkConnectionWidget.h" 23 | #include "RoachAcquisitionServerKATCPClient.h" 24 | 25 | namespace Ui { 26 | class cPlotsWidget; 27 | } 28 | 29 | class cPlotsWidget : public QWidget, public cTCPReceiver::cNotificationCallbackInterface, public cRoachAcquisitionServerKATCPClient::cCallbackInterface 30 | { 31 | Q_OBJECT 32 | 33 | public: 34 | explicit cPlotsWidget(QWidget *pParent = 0); 35 | ~cPlotsWidget(); 36 | 37 | bool isRunning(); 38 | void setIsRunning(bool bIsRunning); 39 | 40 | private: 41 | Ui::cPlotsWidget *m_pUI; 42 | 43 | cFramedQwtLinePlotWidget *m_pPowerPlotWidget; 44 | cFramedQwtLinePlotWidget *m_pStokesPhasePlotWidget; 45 | cBandPowerQwtLinePlot *m_pBandPowerPlotWidget; 46 | 47 | 48 | boost::shared_ptr m_pSocketReceiver; 49 | boost::shared_ptr m_pStreamInterpreter; 50 | 51 | bool m_bIsRunning; 52 | 53 | bool m_bPowerEnabled; 54 | bool m_bStokesPhaseEnabled; 55 | bool m_bBandPowerEnabled; 56 | 57 | QReadWriteLock m_oMutex; 58 | 59 | void getDataThreadFunction(); 60 | QFuture m_oGetDataFuture; 61 | 62 | void updatePlotType(uint16_t u16PlotType); 63 | uint16_t m_u16PlotType; 64 | 65 | uint32_t m_u32AccumulationLength_nFrames; 66 | 67 | void socketConnected_callback(); 68 | void socketDisconnected_callback(); 69 | 70 | //Callbacks from cRoachAcquisitionServerKATCPClient 71 | void connected_callback(bool bConnected, const std::string &strHostAddress, uint16_t u16Port, const std::string &strDescription){} 72 | 73 | void recordingStarted_callback(){} 74 | void recordingStopped_callback(){} 75 | void recordingInfoUpdate_callback(const std::string &strFilename, 76 | int64_t i64StartTime_us, int64_t i64EllapsedTime_us, 77 | int64_t i64StopTime_us, int64_t i64TimeLeft_us, 78 | uint64_t u64CurrentFileSize_B, uint64_t u64DiskSpaceRemaining_B){} 79 | 80 | void stationControllerKATCPConnected_callback(bool bConnected){} 81 | void actualAntennaAz_callback(int64_t i64Timestamp_us, double dAzimuth_deg){} 82 | void actualAntennaEl_callback(int64_t i64Timestamp_us, double dElevation_deg){} 83 | void actualSourceOffsetAz_callback(int64_t i64Timestamp_us, double dAzimuthOffset_deg){} 84 | void actualSourceOffsetEl_callback(int64_t i64Timestamp_us, double dElevationOffset_deg){} 85 | 86 | void frequencyRFChan0_callback(int64_t i64Timestamp_us, double dFrequencyRFChan0_MHz){} 87 | void frequencyRFChan1_callback(int64_t i64Timestamp_us, double dFrequencyRFChan1_MHz){} 88 | 89 | void roachGatewareList_callback(const std::vector &vstrGatewareList){} 90 | void roachKATCPConnected_callback(bool bConnected){} 91 | void stokesEnabled_callback(bool bEnabled){} 92 | void accumulationLength_callback(int64_t i64Timestamp_us, uint32_t u32NFrames); 93 | void coarseChannelSelect_callback(int64_t i64Timestamp_us, uint32_t u32ChannelNo){} 94 | void frequencyFs_callback(double dFrequencyFs_Hz){} 95 | void sizeOfCoarseFFT_callback(uint32_t u32SizeOfCoarseFFT_nSamp){} 96 | void sizeOfFineFFT_callback(uint32_t u32FineFFTSize_nSamp){} 97 | void coarseFFTShiftMask_callback(int64_t i64Timestamp_us, uint32_t u32ShiftMask){} 98 | void attenuationADCChan0_callback(int64_t i64Timestamp_us, double dADCAttenuationChan0_dB){} 99 | void attenuationADCChan1_callback(int64_t i64Timestamp_us, double dADCAttenuationChan1_dB){} 100 | void noiseDiodeEnabled_callback(int64_t i64Timestamp_us, bool bNoideDiodeEnabled){} 101 | void noiseDiodeDutyCycleEnabled_callback(int64_t i64Timestamp_us, bool bNoiseDiodeDutyCyleEnabled){} 102 | void noiseDiodeDutyCycleOnDuration_callback(int64_t i64Timestamp_us, uint32_t u32NAccums){} 103 | void noiseDiodeDutyCycleOffDuration_callback(int64_t i64Timestamp_us, uint32_t u32NAccums){} 104 | void overflowsRegs_callback(int64_t i64Timestamp_us, uint32_t u32OverflowRegs){} 105 | void eth10GbEUp_callback(int64_t i64Timestamp_us, bool bEth10GbEUp){} 106 | void ppsCount_callback(int64_t i64Timestamp_us, uint32_t u32PPSCount){} 107 | void clockFrequency_callback(int64_t i64Timestamp_us, uint32_t u32ClockFrequency_Hz){} 108 | 109 | 110 | public slots: 111 | void slotConnect(int iProtocol, const QString &qstrLocalInterface, unsigned short usLocalPort, 112 | const QString &qstrPeerAddress, unsigned short usPeerPort); 113 | void slotDisconnect(); 114 | void slotPausePlots(); 115 | void slotPausePlots(bool bPause); 116 | void slotResumePlots(); 117 | 118 | //Slots for enabling / disabling plots from outside of this widget 119 | void slotEnablePowerPlot(bool bEnable); 120 | void slotEnableStokesPhasePlot(bool bEnable); 121 | void slotEnableBandPowerPlot(bool bEnable); 122 | 123 | private slots: 124 | //Slots to catch enabling / disabling of groupboxes and in turn fire signals to be emitted to other classes 125 | void slotPowerPlotEnabled(bool bEnabled); 126 | void slotStokesPhasePlotEnabled(bool bEnabled); 127 | void slotBandPowerPlotEnabled(bool bEnabled); 128 | 129 | signals: 130 | void sigConnected(); 131 | void sigDisconnected(); 132 | void sigConnected(bool bIsConnected); 133 | void sigDisconnect(); 134 | 135 | //Signals emitted when plots are enabled on the actual plot widget 136 | void sigPowerPlotEnabled(bool bEnabled); 137 | void sigStokesPhasePlotEnabled(bool bEnabled); 138 | void sigBandPowerPlotEnabled(bool bEnabled); 139 | 140 | }; 141 | 142 | #endif // PLOTSWIDGET_H 143 | -------------------------------------------------------------------------------- /NetworkConnectionWidget.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | cNetworkConnectionWidget 4 | 5 | 6 | 7 | 0 8 | 0 9 | 689 10 | 78 11 | 12 | 13 | 14 | 15 | 0 16 | 0 17 | 18 | 19 | 20 | 21 | 16777215 22 | 78 23 | 24 | 25 | 26 | Network 27 | 28 | 29 | Network 30 | 31 | 32 | 33 | 0 34 | 35 | 36 | 0 37 | 38 | 39 | 0 40 | 41 | 42 | 0 43 | 44 | 45 | 0 46 | 47 | 48 | 49 | 50 | 15 51 | 52 | 53 | 54 | 55 | 56 | 8 57 | 75 58 | true 59 | 60 | 61 | 62 | Data: 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 8 71 | 75 72 | true 73 | 74 | 75 | 76 | Control: 77 | 78 | 79 | 80 | 81 | 82 | 83 | 6 84 | 85 | 86 | 87 | 88 | 89 | 0 90 | 0 91 | 92 | 93 | 94 | 95 | 8 96 | 97 | 98 | 99 | Server 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 8 108 | 109 | 110 | 111 | planck 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 8 120 | 121 | 122 | 123 | : 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 8 132 | 133 | 134 | 135 | 65535 136 | 137 | 138 | 60001 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 0 151 | 0 152 | 153 | 154 | 155 | 156 | 8 157 | 158 | 159 | 160 | Protocol: 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 8 169 | 170 | 171 | 172 | 173 | TCP 174 | 175 | 176 | 177 | 178 | UDP 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 8 188 | 189 | 190 | 191 | Qt::Horizontal 192 | 193 | 194 | 195 | 40 196 | 20 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 8 210 | 211 | 212 | 213 | Local interface 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 8 222 | 223 | 224 | 225 | 0.0.0.0 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 8 234 | 235 | 236 | 237 | : 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 8 246 | 247 | 248 | 249 | 65535 250 | 251 | 252 | 60001 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 8 263 | 264 | 265 | 266 | Enable KATCP Control 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 8 277 | 278 | 279 | 280 | Port 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 8 289 | 290 | 291 | 292 | 65535 293 | 294 | 295 | 7147 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 8 304 | 305 | 306 | 307 | Qt::Horizontal 308 | 309 | 310 | 311 | 40 312 | 20 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 8 324 | 325 | 326 | 327 | Connect 328 | 329 | 330 | P 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | -------------------------------------------------------------------------------- /RoachAcquisitionServerKATCPClient.h: -------------------------------------------------------------------------------- 1 | #ifndef ROACH_ACQUISITION_SERVER_KATCP_CLIENT_H 2 | #define ROACH_ACQUISITION_SERVER_KATCP_CLIENT_H 3 | 4 | //System includes 5 | 6 | //Library includes 7 | 8 | //Local includes 9 | #include "AVNAppLibs/KATCP/KATCPClientBase.h" 10 | 11 | //This KATCP client is implemented manually using a client TCP socket and not the KATCP library. 12 | //This makes portability a bit better especially with Windows. 13 | 14 | class cRoachAcquisitionServerKATCPClient : public cKATCPClientBase 15 | { 16 | public: 17 | class cCallbackInterface : public cKATCPClientBase::cCallbackInterface 18 | { 19 | public: 20 | virtual void recordingStarted_callback() = 0; 21 | virtual void recordingStopped_callback() = 0; 22 | virtual void recordingInfoUpdate_callback(const std::string &strFilename, 23 | int64_t i64StartTime_us, int64_t i64EllapsedTime_us, 24 | int64_t i64StopTime_us, int64_t i64TimeLeft_us, 25 | uint64_t u64CurrentFileSize_B, uint64_t u64DiskSpaceRemaining_B) = 0; 26 | 27 | virtual void stationControllerKATCPConnected_callback(bool bConnected) = 0; 28 | virtual void actualAntennaAz_callback(int64_t i64Timestamp_us, double dAzimuth_deg) = 0; 29 | virtual void actualAntennaEl_callback(int64_t i64Timestamp_us, double dElevation_deg) = 0; 30 | virtual void actualSourceOffsetAz_callback(int64_t i64Timestamp_us, double dAzimuthOffset_deg) = 0; 31 | virtual void actualSourceOffsetEl_callback(int64_t i64Timestamp_us, double dElevationOffset_deg) = 0; 32 | 33 | virtual void frequencyRFChan0_callback(int64_t i64Timestamp_us, double dFrequencyRFChan0_MHz) = 0; 34 | virtual void frequencyRFChan1_callback(int64_t i64Timestamp_us, double dFrequencyRFChan1_MHz) = 0; 35 | 36 | virtual void roachGatewareList_callback(const std::vector &vstrGatewareList) = 0; 37 | virtual void roachKATCPConnected_callback(bool bConnected) = 0; 38 | virtual void stokesEnabled_callback(bool bEnabled) = 0; 39 | virtual void accumulationLength_callback(int64_t i64Timestamp_us, uint32_t u32NFrames) = 0; 40 | virtual void coarseChannelSelect_callback(int64_t i64Timestamp_us, uint32_t u32ChannelNo) = 0; 41 | virtual void frequencyFs_callback(double dFrequencyFs_Hz) = 0; 42 | virtual void sizeOfCoarseFFT_callback(uint32_t u32SizeOfCoarseFFT_nSamp) = 0; 43 | virtual void sizeOfFineFFT_callback(uint32_t u32FineFFTSize_nSamp) = 0; 44 | virtual void coarseFFTShiftMask_callback(int64_t i64Timestamp_us, uint32_t u32ShiftMask) = 0; 45 | virtual void attenuationADCChan0_callback(int64_t i64Timestamp_us, double dADCAttenuationChan0_dB) = 0; 46 | virtual void attenuationADCChan1_callback(int64_t i64Timestamp_us, double dADCAttenuationChan1_dB) = 0; 47 | virtual void noiseDiodeEnabled_callback(int64_t i64Timestamp_us, bool bNoideDiodeEnabled) = 0; 48 | virtual void noiseDiodeDutyCycleEnabled_callback(int64_t i64Timestamp_us, bool bNoiseDiodeDutyCyleEnabled) = 0; 49 | virtual void noiseDiodeDutyCycleOnDuration_callback(int64_t i64Timestamp_us, uint32_t u32NAccums) = 0; 50 | virtual void noiseDiodeDutyCycleOffDuration_callback(int64_t i64Timestamp_us, uint32_t u32NAccums) = 0; 51 | virtual void overflowsRegs_callback(int64_t i64Timestamp_us, uint32_t u32OverflowRegs) = 0; 52 | virtual void eth10GbEUp_callback(int64_t i64Timestamp_us, bool bEth10GbEUp) = 0; 53 | virtual void ppsCount_callback(int64_t i64Timestamp_us, uint32_t u32PPSCount) = 0; 54 | virtual void clockFrequency_callback(int64_t i64Timestamp_us, uint32_t u32ClockFrequency_Hz) = 0; 55 | 56 | }; 57 | 58 | cRoachAcquisitionServerKATCPClient(); 59 | ~cRoachAcquisitionServerKATCPClient(); 60 | 61 | //Client requests 62 | void requestStartRecording(const std::string &strFilenamePrefix = std::string(""), 63 | int64_t i64StartTime_us = 0, int64_t i64Duration_us = 0); 64 | void requestStopRecording(); 65 | void requestRecordingStatus(); 66 | void requestRecordingInfoUpdate(); 67 | 68 | void requestRoachGatewareList(); 69 | void requestRoachProgram(const std::string strScriptPath); 70 | void requestRoachSetStokesEnabled(bool bEnabled); 71 | void requestRoachSetAccumulationLength(uint32_t u32Length_nFrames); 72 | void requestRoachSetCoarseChannelSelect(uint32_t u32ChannelNo); 73 | void requestRoachSetCoarseFFTShiftMask(uint32_t u32FFTShiftMask); 74 | void requestRoachSetADC0Attenuation(uint32_t u32ADC0Attenuation); 75 | void requestRoachSetADC1Attenuation(uint32_t u32ADC1Attenuation); 76 | void requestRoachSetNoiseDiodeEnabled(bool bEnabled); 77 | void requestRoachSetNoiseDiodeDutyCycleEnabled(bool bEnabled); 78 | void requestRoachSetNoiseDiodeDutyCycleOnDuration(uint32_t u32NAccums); 79 | void requestRoachSetNoiseDiodeDutyCycleOffDuration(uint32_t u32NAccums); 80 | 81 | void subscribeToSensors(); 82 | 83 | private: 84 | //Implement from base class 85 | void processKATCPMessage(const std::vector &vstrMessageTokens); 86 | void onConnected(); 87 | 88 | //Notifications sent to all callback handlers 89 | void sendRecordingStarted(); 90 | void sendRecordingStopped(); 91 | void sendRecordingInfoUpdate(const std::string &strFilename, 92 | int64_t i64StartTime_us, int64_t i64EllapsedTime_us, 93 | int64_t i64StopTime_us, int64_t i64TimeLeft_us, 94 | uint64_t u64CurrentFileSize_B, uint64_t u64DiskSpaceRemaining_B); 95 | 96 | void sendStationControllerKATCPConnected(bool bConnected); 97 | void sendActualAntennaAz(int64_t i64Timestamp_us,double dAzimuth_deg); 98 | void sendActualAntennaEl(int64_t i64Timestamp_us,double dElevation_deg); 99 | void sendActualSourceOffsetAz(int64_t i64Timestamp_us, double dAzimuthOffset_deg); 100 | void sendActualSourceOffsetEl(int64_t i64Timestamp_us, double dElevationOffset_deg); 101 | 102 | void sendFrequencyRFChan0(int64_t i64Timestamp_us, double dFreqencyRF_MHz); 103 | void sendFrequencyRFChan1(int64_t i64Timestamp_us, double dFreqencyRF_MHz); 104 | 105 | void sendRoachGatewareList(const std::vector &vstrGatewareList); 106 | void sendRoachKATCPConnected(bool bConnected); 107 | void sendStokesEnabled(bool bEnabled); 108 | void sendAccumulationLength(int64_t i64Timestamp_us, uint32_t u32NFrames); 109 | void sendCoarseChannelSelect(int64_t i64Timestamp_us, uint32_t u32ChannelNo); 110 | void sendFrequencyFs(double dFrequencyFs_Hz); 111 | void sendSizeOfCoarseFFT(uint32_t u32SizeOfCoarseFFT_nSamp); 112 | void sendSizeOfFineFFT(uint32_t u32FineFFTSize_nSamp); 113 | void sendCoarseFFTShiftMask(int64_t i64Timestamp_us, uint32_t u32ShiftMask); 114 | void sendAttenuationADCChan0(int64_t i64Timestamp_us, double dADCAttenuationChan0_dB); 115 | void sendAttenuationADCChan1(int64_t i64Timestamp_us, double dADCAttenuationChan1_dB); 116 | void sendNoiseDiodeEnabled(int64_t i64Timestamp_us, bool bNoideDiodeEnabled); 117 | void sendNoiseDiodeDutyCycleEnabled(int64_t i64Timestamp_us, bool bNoiseDiodeDutyCyleEnabled); 118 | void sendNoiseDiodeDutyCycleOnDuration(int64_t i64Timestamp_us, uint32_t u32NAccums); 119 | void sendNoiseDiodeDutyCycleOffDuration(int64_t i64Timestamp_us, uint32_t u32NAccums); 120 | void sendOverflowsRegs(int64_t i64Timestamp_us, uint32_t u32OverflowRegs); 121 | void sendEth10GbEUp(int64_t i64Timestamp_us, bool bEth10GbEUp); 122 | void sendPPSCount(int64_t i64Timestamp_us, uint32_t u32PPSCount); 123 | void sendClockFrequency(int64_t i64Timestamp_us, uint32_t u32ClockFrequency_Hz); 124 | 125 | 126 | }; 127 | 128 | #endif // ROACH_ACQUISITION_SERVER_KATCP_CLIENT_H 129 | -------------------------------------------------------------------------------- /RoachAcquistionControlWidget.h: -------------------------------------------------------------------------------- 1 | #ifndef ROACH_ACQUISITION_CONTROL_WIDGET_H 2 | #define ROACH_ACQUISITION_CONTROL_WIDGET_H 3 | 4 | //System includes 5 | 6 | //Libary includes 7 | #include 8 | #include 9 | #include 10 | 11 | #ifndef Q_MOC_RUN //Qt's MOC and Boost have some issues don't let MOC process boost headers 12 | #include 13 | #endif 14 | 15 | //Local includes 16 | #include "RoachAcquisitionServerKATCPClient.h" 17 | #include "PlotsWidget.h" 18 | 19 | namespace Ui { 20 | class cRoachAcquistionControlWidget; 21 | } 22 | 23 | class cRoachAcquistionControlWidget : public QDialog, public cRoachAcquisitionServerKATCPClient::cCallbackInterface 24 | { 25 | Q_OBJECT 26 | 27 | public: 28 | explicit cRoachAcquistionControlWidget(cPlotsWidget *pPlotsWidget, QWidget *pParent = 0); 29 | ~cRoachAcquistionControlWidget(); 30 | 31 | bool connect(const QString &qstrHostname, uint16_t u16Port); 32 | 33 | private: 34 | Ui::cRoachAcquistionControlWidget *m_pUI; 35 | cPlotsWidget *m_pPlotsWidget; 36 | 37 | QTimer m_oSecondTimer; 38 | QTimer m_oTwoSecondTimer; 39 | QTimer m_o200msTimer; 40 | 41 | Qt::TimeSpec m_eTimeSpec; 42 | 43 | bool m_bIsRecording; 44 | 45 | boost::shared_ptr m_pKATCPClient; 46 | 47 | QReadWriteLock m_oMutex; 48 | 49 | //Station controller and Roach parameters 50 | bool m_bStationControllerKATCPConnected; 51 | double m_dFrequencyRFChan0_MHz; 52 | double m_dFrequencyRFChan1_MHz; 53 | 54 | std::vector m_vstrRoachGatewareList; 55 | bool m_bRoachKATCPConnected; 56 | bool m_bStokesEnabled; 57 | uint32_t m_u32AccumulationLength_nFrames; 58 | double m_dSingleAccumulationLength_ms; 59 | uint32_t m_u32CoarseChannelSelect; 60 | double m_dCoarseChannelSelectBaseband_MHz; 61 | double m_dFrequencyFs_Hz; 62 | uint32_t m_u32SizeOfCoarseFFT_nSamp; 63 | uint32_t m_u32SizeOfFineFFT_nSamp; 64 | uint32_t m_u32CoarseFFTShiftMask; 65 | double m_dAttenuationADCChan0_dB; 66 | double m_dAttenuationADCChan1_dB; 67 | bool m_bNoiseDiodeEnabled; 68 | bool m_bNoiseDiodeDutyCycleEnabled; 69 | uint32_t m_u32NoiseDiodeDutyCycleOnDuration_nAccs; 70 | uint32_t m_u32NoiseDiodeDutyCycleOffDuration_nAccs; 71 | uint32_t m_u32OverflowsRegs; 72 | bool m_bEth10GbEUp; 73 | uint32_t m_u32PPSCount; 74 | uint32_t m_u32PreviousPPSCount; 75 | bool m_bPPSValid; 76 | uint32_t m_u32ClockFrequency_Hz; 77 | 78 | boost::mutex m_oParameterMutex; 79 | 80 | void connectSignalToSlots(); 81 | 82 | //Implemented callbacks from cRoachAcquisitionServerKATCPClient::cCallbackInterface 83 | void connected_callback(bool bConnected, const std::string &strHostAddress, uint16_t u16Port, const std::string &strDescription); 84 | void recordingStarted_callback(); 85 | void recordingStopped_callback(); 86 | void recordingInfoUpdate_callback(const std::string &strFilename, 87 | int64_t i64StartTime_us, int64_t i64EllapsedTime_us, 88 | int64_t i64StopTime_us, int64_t i64TimeLeft_us, 89 | uint64_t u64CurrentFileSize_B, uint64_t u64DiskSpaceRemaining_B); 90 | 91 | void stationControllerKATCPConnected_callback(bool bConnected); 92 | void actualAntennaAz_callback(int64_t i64Timestamp_us, double dAzimuth_deg); 93 | void actualAntennaEl_callback(int64_t i64Timestamp_us, double dElevation_deg); 94 | void actualSourceOffsetAz_callback(int64_t i64Timestamp_us, double dAzimuthOffset_deg); 95 | void actualSourceOffsetEl_callback(int64_t i64Timestamp_us, double dElevationOffset_deg); 96 | 97 | void frequencyRFChan0_callback(int64_t i64Timestamp_us, double dFrequencyRFChan0_MHz); 98 | void frequencyRFChan1_callback(int64_t i64Timestamp_us, double dFrequencyRFChan1_MHz); 99 | 100 | void roachGatewareList_callback(const std::vector &vstrGatewareList); 101 | void roachKATCPConnected_callback(bool bConnected); 102 | void stokesEnabled_callback(bool bEnabled); 103 | void accumulationLength_callback(int64_t i64Timestamp_us, uint32_t u32NFrames); 104 | void coarseChannelSelect_callback(int64_t i64Timestamp_us, uint32_t u32ChannelNo); 105 | void frequencyFs_callback(double dFrequencyFs_Hz); 106 | void sizeOfCoarseFFT_callback(uint32_t u32SizeOfCoarseFFT_nSamp); 107 | void sizeOfFineFFT_callback(uint32_t u32SizeOfFineFFT_nSamp); 108 | void coarseFFTShiftMask_callback(int64_t i64Timestamp_us, uint32_t u32ShiftMask); 109 | void attenuationADCChan0_callback(int64_t i64Timestamp_us, double dADCAttenuationChan0_dB); 110 | void attenuationADCChan1_callback(int64_t i64Timestamp_us, double dADCAttenuationChan1_dB); 111 | void noiseDiodeEnabled_callback(int64_t i64Timestamp_us, bool bNoiseDiodeEnabled); 112 | void noiseDiodeDutyCycleEnabled_callback(int64_t i64Timestamp_us, bool bNoiseDiodeDutyCyleEnabled); 113 | void noiseDiodeDutyCycleOnDuration_callback(int64_t i64Timestamp_us, uint32_t u32NAccums); 114 | void noiseDiodeDutyCycleOffDuration_callback(int64_t i64Timestamp_us, uint32_t u32NAccums); 115 | void overflowsRegs_callback(int64_t i64Timestamp_us, uint32_t u32OverflowRegs); 116 | void eth10GbEUp_callback(int64_t i64Timestamp_us, bool bEth10GbEUp); 117 | void ppsCount_callback(int64_t i64Timestamp_us, uint32_t u32PPSCount); 118 | void clockFrequency_callback(int64_t i64Timestamp_us, uint32_t u32ClockFrequency_Hz); 119 | 120 | void closeEvent(QCloseEvent *pEvent); //Overload to hide instead of close on clicking close 121 | 122 | void checkParametersValid(); 123 | 124 | private slots: 125 | void slotSecondTimerTrigger(); 126 | void slot200msTimerTriger(); 127 | void slotTwoSecondTimerTrigger(); 128 | void slotStartStopRecordingClicked(); 129 | void slotRecordingInfoUpdate(const QString &qstrFilename, 130 | int64_t i64StartTime_us, int64_t i64EllapsedTime_us, 131 | int64_t i64StopTime_us, int64_t i64TimeLeft_us, 132 | uint64_t u64CurrentFileSize_B, uint64_t u64DiskSpaceRemaining_B); 133 | void slotRecordingStarted(); 134 | void slotRecordingStoppped(); 135 | void slotTimeZoneChanged(QString qstrTimeZone); 136 | 137 | //Update display Roach parameters in the GUI (These are needed for queued connections 138 | void slotUpdateRoachGUIParameters(); 139 | void slotUpdateRoachGatewareList(); 140 | 141 | //Slots for push buttons for Roach control 142 | void slotRefreshGatewareList(); 143 | void slotProgram(); 144 | void slotToggleStokes(); 145 | void slotSendAccumulationLength_nFrames(); 146 | void slotSendAccumulationLength_ms(); 147 | void slotSendCoarseChannelSelect_binNo(); 148 | void slotSendCoarseChannelSelect_baseband(); 149 | void slotSendCoarseChannelSelect_finalIF(); 150 | void slotSendCoarseChannelSelect_RF0(); 151 | void slotSendCoarseChannelSelect_RF1(); 152 | void slotSendCoarseFFTShiftMask(); 153 | void slotSendADC0Attenuation(); 154 | void slotSendADC1Attenuation(); 155 | void slotToggleNoiseDiodeEnabled(); 156 | void slotToggleNoiseDiodeDutyCycleEnabled(); 157 | void slotSendNoiseDiodeDutyCycleOnDuration_nAccums(); 158 | void slotSendNoiseDiodeDutyCycleOnDuration_ms(); 159 | void slotSendNoiseDiodeDutyCycleOffDuration_nAccums(); 160 | void slotSendNoiseDiodeDutyCycleOffDuration_ms(); 161 | 162 | 163 | 164 | signals: 165 | void sigRecordingInfoUpdate(const QString &qstrFilename, 166 | int64_t i64StartTime_us, int64_t i64EllapsedTime_us, 167 | int64_t i64StopTime_us, int64_t i64TimeLeft_us, 168 | uint64_t u64CurrentFileSize_B, uint64_t u64DiskSpaceRemaining_B); 169 | void sigRecordingStarted(); 170 | void sigRecordingStoppped(); 171 | 172 | void sigUpdateRoachGatewareList(); 173 | 174 | }; 175 | 176 | #endif // ROACH_ACQUISITION_CONTROL_WIDGET_H 177 | -------------------------------------------------------------------------------- /AboutDialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | AboutDialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 485 10 | 467 11 | 12 | 13 | 14 | 15 | 0 16 | 0 17 | 18 | 19 | 20 | 21 | 485 22 | 465 23 | 24 | 25 | 26 | 27 | 485 28 | 493 29 | 30 | 31 | 32 | About ARDView 33 | 34 | 35 | 36 | :/Images/Images/about.png:/Images/Images/about.png 37 | 38 | 39 | 40 | 41 | 42 | 43 | 0 44 | 1 45 | 46 | 47 | 48 | 49 | 8 50 | 51 | 52 | 53 | QFrame::StyledPanel 54 | 55 | 56 | QFrame::Raised 57 | 58 | 59 | 60 | 4 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 0 69 | 0 70 | 71 | 72 | 73 | 74 | 77 75 | 73 76 | 77 | 78 | 79 | 80 | 8 81 | 82 | 83 | 84 | 85 | 86 | 87 | :/Images/Images/AVNLogo.png 88 | 89 | 90 | true 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 0 99 | 0 100 | 101 | 102 | 103 | 104 | LMMathItalic9 105 | 8 106 | 75 107 | true 108 | 109 | 110 | 111 | AVNSignalAnalyser 112 | 113 | 114 | Qt::AlignCenter 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 8 125 | 126 | 127 | 128 | Version: x.x.x 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 8 137 | 138 | 139 | 140 | Platform: OS_wordLength 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 8 149 | 150 | 151 | 152 | Build date: dd MMM yyyy 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 8 161 | 162 | 163 | 164 | Qt::Horizontal 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 0 175 | 0 176 | 177 | 178 | 179 | 180 | 60 181 | 64 182 | 183 | 184 | 185 | 186 | 60 187 | 64 188 | 189 | 190 | 191 | 192 | 8 193 | 194 | 195 | 196 | 197 | 198 | 199 | :/Images/Images/SKALogo.png 200 | 201 | 202 | true 203 | 204 | 205 | Qt::AlignCenter 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 8 216 | 75 217 | true 218 | 219 | 220 | 221 | African VLBI Network 222 | 223 | 224 | Qt::AlignCenter 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 8 233 | 234 | 235 | 236 | SKA South Africa 237 | 238 | 239 | Qt::AlignCenter 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 8 248 | 249 | 250 | 251 | <html><head/><body><p><a href="http://www.cr.uct.ac.za/"><span style=" text-decoration: underline; color:#0000ff;">http://www.ska.ac.za/</span></a></p></body></html> 252 | 253 | 254 | Qt::RichText 255 | 256 | 257 | Qt::AlignCenter 258 | 259 | 260 | true 261 | 262 | 263 | Qt::TextBrowserInteraction 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 8 276 | 277 | 278 | 279 | Qt::Horizontal 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 8 288 | 75 289 | true 290 | 291 | 292 | 293 | Author: 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 8 302 | 303 | 304 | 305 | Craig Tong 306 | 307 | 308 | Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 8 317 | 318 | 319 | 320 | ctong@ska.ac.za 321 | 322 | 323 | Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 8 332 | 333 | 334 | 335 | Copyright © 2015 SKA SA 336 | 337 | 338 | Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 8 347 | 348 | 349 | 350 | Qt::Horizontal 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 0 359 | 0 360 | 361 | 362 | 363 | 364 | 8 365 | 366 | 367 | 368 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> 369 | <html><head><meta name="qrichtext" content="1" /><style type="text/css"> 370 | p, li { white-space: pre-wrap; } 371 | </style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:6pt; font-weight:400; font-style:normal;"> 372 | <p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:7pt;">AVNSignalAnalyser is based in part on the work of the Qwt project</span></p> 373 | <p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://qwt.sf.net"><span style=" font-family:'Sans Serif'; font-size:7pt; text-decoration: underline; color:#0000ff;">(http://qwt.sf.net)</span></a></p> 374 | <p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif'; font-size:7pt;">This software comes with absolutely no warranty. Use at your own risk.</span></p> 375 | <p align="center" style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:7pt; text-decoration: underline; color:#0000ff;"><br /></p></body></html> 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 8 387 | 388 | 389 | 390 | QFrame::StyledPanel 391 | 392 | 393 | QFrame::Raised 394 | 395 | 396 | 397 | 398 | 399 | 400 | 8 401 | 402 | 403 | 404 | Qt::Horizontal 405 | 406 | 407 | 408 | 237 409 | 20 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 8 419 | 420 | 421 | 422 | Close 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | closeButton 437 | clicked() 438 | AboutDialog 439 | close() 440 | 441 | 442 | 308 443 | 311 444 | 445 | 446 | 185 447 | 172 448 | 449 | 450 | 451 | 452 | 453 | -------------------------------------------------------------------------------- /PlotsWidget.cpp: -------------------------------------------------------------------------------- 1 | //System includes 2 | #include 3 | #include 4 | 5 | //Library includes 6 | #include 7 | 8 | #ifndef Q_MOC_RUN //Qt's MOC and Boost have some issues don't let MOC process boost headers 9 | #include 10 | #endif 11 | 12 | //Local includes 13 | #include "PlotsWidget.h" 14 | #include "ui_PlotsWidget.h" 15 | 16 | #include "AVNDataTypes/SpectrometerDataStream/SpectrometerDefinitions.h" 17 | 18 | using namespace std; 19 | 20 | cPlotsWidget::cPlotsWidget(QWidget *pParent) : 21 | QWidget(pParent), 22 | m_pUI(new Ui::cPlotsWidget), 23 | m_pPowerPlotWidget(new cFramedQwtLinePlotWidget(this)), 24 | m_pStokesPhasePlotWidget(new cFramedQwtLinePlotWidget(this)), 25 | m_pBandPowerPlotWidget(new cBandPowerQwtLinePlot(this)), 26 | m_bPowerEnabled(true), 27 | m_bStokesPhaseEnabled(true), 28 | m_bBandPowerEnabled(true), 29 | m_u16PlotType(AVN::Spectrometer::UNDEFINED), 30 | m_u32AccumulationLength_nFrames(1) 31 | { 32 | m_pUI->setupUi(this); 33 | 34 | updatePlotType(AVN::Spectrometer::UNDEFINED); //Launch in a safe state (Unknown plot type rejects sample data). This will change when a known stream type is identified. 35 | 36 | m_pUI->horizontalLayout_powers->insertWidget(0, m_pPowerPlotWidget); 37 | m_pUI->horizontalLayout_stokesPhase->insertWidget(0, m_pStokesPhasePlotWidget); 38 | m_pUI->horizontalLayout_bandPower->insertWidget(0, m_pBandPowerPlotWidget); 39 | 40 | //Use differnt colours for StokesPhase assumes 2 channels 41 | m_pStokesPhasePlotWidget->m_qveCurveColours.erase(m_pStokesPhasePlotWidget->m_qveCurveColours.begin(), m_pStokesPhasePlotWidget->m_qveCurveColours.begin() + 2); 42 | 43 | m_pBandPowerPlotWidget->setSpanLengthControlScalingFactor(1, QString("s")); //Band power span is in seconds: 44 | 45 | //Plot enabling/disabling 46 | //When the groupboxes for any of the 3 plots types are enabled or disabled catch and fire a signal off from this class 47 | QObject::connect(m_pUI->groupBox_powers, SIGNAL(clicked(bool)), this, SLOT(slotPowerPlotEnabled(bool))); 48 | QObject::connect(m_pUI->groupBox_stokesPhase, SIGNAL(clicked(bool)), this, SLOT(slotStokesPhasePlotEnabled(bool))); 49 | QObject::connect(m_pUI->groupBox_bandPower, SIGNAL(clicked(bool)), this, SLOT(slotBandPowerPlotEnabled(bool))); 50 | 51 | //Vertical lines for intergrated bandwidth 52 | QObject::connect(m_pBandPowerPlotWidget, SIGNAL(sigSelectedBandChanged(QVector)), m_pPowerPlotWidget, SLOT(slotDrawVerticalLines(QVector))); 53 | QObject::connect(m_pBandPowerPlotWidget, SIGNAL(sigSelectedBandChanged(QVector)), m_pStokesPhasePlotWidget, SLOT(slotDrawVerticalLines(QVector))); 54 | 55 | //SocketStreamer triggered disconnect 56 | QObject::connect(this, SIGNAL(sigDisconnect()), this, SLOT(slotDisconnect()), Qt::QueuedConnection); //Must be queued to prevent the socket reading thread try to join itself. 57 | 58 | //Connect Zoom of X axis together 59 | QObject::connect(m_pPowerPlotWidget, SIGNAL(sigXScaleDivChanged(double,double)), m_pStokesPhasePlotWidget, SLOT(slotUpdateXScaleDiv(double,double)) ); 60 | QObject::connect(m_pStokesPhasePlotWidget, SIGNAL(sigXScaleDivChanged(double,double)), m_pPowerPlotWidget, SLOT(slotUpdateXScaleDiv(double,double)) ); 61 | 62 | //Connect mouse position indicator of power and stoke/phase plots together. 63 | QObject::connect(m_pPowerPlotWidget, SIGNAL(sigSharedMousePositionChanged(QPointF,bool)), m_pStokesPhasePlotWidget, SLOT(slotUpdateSharedMouseHPosition(QPointF,bool)) ); 64 | QObject::connect(m_pStokesPhasePlotWidget, SIGNAL(sigSharedMousePositionChanged(QPointF,bool)), m_pPowerPlotWidget, SLOT(slotUpdateSharedMouseHPosition(QPointF,bool)) ); 65 | } 66 | 67 | cPlotsWidget::~cPlotsWidget() 68 | { 69 | setIsRunning(false); 70 | 71 | //Wait for data fetching thread to exit 72 | m_oGetDataFuture.waitForFinished(); 73 | 74 | delete m_pUI; 75 | } 76 | 77 | void cPlotsWidget::slotConnect(int iDataProtocol, const QString &qstrLocalInterface, unsigned short usLocalPort, const QString &qstrPeerAddress, unsigned short usPeerPort) 78 | { 79 | //Create and start the socket receiver depending on protocol 80 | switch(cNetworkConnectionWidget::dataProtocol(iDataProtocol)) 81 | { 82 | case cNetworkConnectionWidget::TCP: 83 | m_pSocketReceiver = boost::make_shared(qstrPeerAddress.toStdString(), usPeerPort); 84 | 85 | //Register this class instance to get notification callbacks about socket connectivity. 86 | boost::static_pointer_cast(m_pSocketReceiver)->registerNoticationCallbackHandler(this); 87 | 88 | break; 89 | 90 | case cNetworkConnectionWidget::UDP: 91 | m_pSocketReceiver = boost::make_shared(qstrLocalInterface.toStdString(), usLocalPort, qstrPeerAddress.toStdString(), usPeerPort); 92 | break; 93 | 94 | default: 95 | //Return if protocol unknown. Should never happen 96 | return; 97 | } 98 | 99 | m_pStreamInterpreter = boost::make_shared(m_pSocketReceiver); 100 | m_pStreamInterpreter->setUpdateRate(33); 101 | 102 | m_pSocketReceiver->startReceiving(); 103 | 104 | //Start the thread which retrieves data, formats and sends to the plotter widgetts 105 | setIsRunning(true); 106 | m_oGetDataFuture = QtConcurrent::run(this, &cPlotsWidget::getDataThreadFunction); 107 | } 108 | 109 | void cPlotsWidget::slotDisconnect() 110 | { 111 | //Stop the thread sending data to the plotter. 112 | setIsRunning(false); 113 | 114 | //Block until this is done 115 | cout << "cPlotsWidget::slotDisconnect(): Waiting for getDataThread to stop..." << endl; 116 | m_oGetDataFuture.waitForFinished(); 117 | 118 | //Stop the TCP receiver and interpreter 119 | 120 | cout << "cPlotsWidget::slotDisconnect(): Closing SpectrometerDataStreamInterpreter..." << endl; 121 | 122 | m_pStreamInterpreter.reset(); 123 | 124 | cout << "cPlotsWidget::slotDisconnect(): SpectrometerDataStreamInterpreter destroyed..." << endl; 125 | 126 | cout << "cPlotsWidget::slotDisconnect(): Closing SocketReceiver..." << endl; 127 | 128 | m_pSocketReceiver.reset(); 129 | 130 | cout << "cPlotsWidget::slotDisconnect(): SocketReceiver destroyed." << endl; 131 | 132 | sigDisconnected(); 133 | sigConnected(false); 134 | } 135 | 136 | void cPlotsWidget::slotPausePlots(bool bPause) 137 | { 138 | m_pPowerPlotWidget->slotPause(bPause); 139 | m_pStokesPhasePlotWidget->slotPause(bPause); 140 | m_pBandPowerPlotWidget->slotPause(bPause); 141 | } 142 | 143 | void cPlotsWidget::slotPausePlots() 144 | { 145 | slotPausePlots(true); 146 | } 147 | 148 | void cPlotsWidget::slotResumePlots() 149 | { 150 | slotPausePlots(false); 151 | } 152 | 153 | bool cPlotsWidget::isRunning() 154 | { 155 | QReadLocker oReadLock(&m_oMutex); 156 | 157 | return m_bIsRunning; 158 | } 159 | 160 | void cPlotsWidget::setIsRunning(bool bIsRunning) 161 | { 162 | { 163 | QWriteLocker oWriteLock(&m_oMutex); 164 | m_bIsRunning = bIsRunning; 165 | } 166 | 167 | if(m_pStreamInterpreter.get()) 168 | { 169 | m_pStreamInterpreter->setIsRunning(bIsRunning); 170 | } 171 | } 172 | 173 | void cPlotsWidget::getDataThreadFunction() 174 | { 175 | cout << "Entered cPlotsWidget::getDataThreadFunction()" << endl; 176 | 177 | //Thread function fetching data from TCP Receiver and conditioning for plotting. 178 | 179 | //Variables and vectors used for plot data: 180 | QVector > qvvfPlotData; 181 | qvvfPlotData.resize(4); 182 | 183 | QVector qvu32PowerLRChanList; 184 | qvu32PowerLRChanList.push_back(0); 185 | qvu32PowerLRChanList.push_back(1); 186 | 187 | QVector qvu32StokesPhaseQUChanList; 188 | qvu32StokesPhaseQUChanList.push_back(2); 189 | qvu32StokesPhaseQUChanList.push_back(3); 190 | 191 | QVector qvu32RelativePhaseChanList; 192 | qvu32RelativePhaseChanList.push_back(2); 193 | 194 | float *fpChan0 = NULL; 195 | float *fpChan1 = NULL; 196 | float *fpChan2 = NULL; 197 | float *fpChan3 = NULL; 198 | 199 | while(isRunning()) 200 | { 201 | while(!m_pStreamInterpreter->synchronise()) 202 | { 203 | if(!isRunning()) 204 | return; 205 | } 206 | 207 | //After synchronisation stream parameter are available so... 208 | 209 | //Resize plot vectors as necessary 210 | if((uint32_t)qvvfPlotData[0].size() != m_pStreamInterpreter->getNValuesPerChannelPerFrame()) 211 | { 212 | for(uint32_t ui = 0; ui < (uint32_t)qvvfPlotData.size(); ui++) 213 | { 214 | qvvfPlotData[ui].resize(m_pStreamInterpreter->getNValuesPerChannelPerFrame()); 215 | } 216 | } 217 | 218 | //Some pointers for copying data values 219 | fpChan0 = &qvvfPlotData[0].front(); 220 | fpChan1 = &qvvfPlotData[1].front(); 221 | fpChan2 = &qvvfPlotData[2].front(); 222 | fpChan3 = &qvvfPlotData[3].front(); 223 | 224 | //Update plotting widget to plot data correctly 225 | updatePlotType(m_pStreamInterpreter->getLastHeader().getDigitiserType()); 226 | 227 | while(isRunning()) 228 | { 229 | //Some pointers for copying data values 230 | fpChan0 = &qvvfPlotData[0].front(); 231 | fpChan1 = &qvvfPlotData[1].front(); 232 | fpChan2 = &qvvfPlotData[2].front(); 233 | fpChan3 = &qvvfPlotData[3].front(); 234 | 235 | 236 | //Get the data from the next frame. Return false means an inconsistency was incountered 237 | if(!m_pStreamInterpreter->getNextFrame(fpChan0, fpChan1, fpChan2, fpChan3, qvvfPlotData[0].size())) 238 | { 239 | break; //Causes resync 240 | } 241 | 242 | //Calculate phase for LRPP mode 243 | switch(m_pStreamInterpreter->getLastHeader().getDigitiserType()) 244 | { 245 | case AVN::Spectrometer::WB_SPECTROMETER_LRPP: 246 | case AVN::Spectrometer::NB_SPECTROMETER_LRPP: 247 | { 248 | QReadLocker oLock(&m_oMutex); 249 | 250 | for(uint32_t ui = 0; ui < (uint32_t)qvvfPlotData[0].size(); ui++) 251 | { 252 | //Phase calculations: Store relative phase between ADC0 and ADC1 in Chan2 in progressive frequency bins 253 | //Phase for ADC0 and ADC1 in channels 2 and 3 respectively 254 | 255 | //Phase is calculated in FPGA as a Fixed 18_15 value in radians (18 bits. 15 lower 15 of which are fractional). 256 | //The decimal point is ignored and the values are accumulated to a 32 bit signed integer 257 | //for interpretation by a x86 platform. 258 | //So we need to rescale back to radians: 259 | 260 | *fpChan2 = ( *fpChan2 / 32768) - ( *fpChan3 / 32768); 261 | *fpChan2 /= m_u32AccumulationLength_nFrames; //Divide out accumulation length 262 | 263 | fpChan2++; 264 | fpChan3++; 265 | } 266 | 267 | if(m_bPowerEnabled) 268 | { 269 | m_pPowerPlotWidget->addData(qvvfPlotData, m_pStreamInterpreter->getLastHeader().getTimestamp_us(), qvu32PowerLRChanList); 270 | } 271 | 272 | if(m_bStokesPhaseEnabled) 273 | { 274 | m_pStokesPhasePlotWidget->addData(qvvfPlotData, m_pStreamInterpreter->getLastHeader().getTimestamp_us(), qvu32RelativePhaseChanList); 275 | } 276 | 277 | if(m_bBandPowerEnabled) 278 | { 279 | m_pBandPowerPlotWidget->addData(qvvfPlotData, m_pStreamInterpreter->getLastHeader().getTimestamp_us(), qvu32PowerLRChanList); 280 | } 281 | 282 | break; 283 | } 284 | 285 | case AVN::Spectrometer::WB_SPECTROMETER_LRQU: 286 | case AVN::Spectrometer::NB_SPECTROMETER_LRQU: 287 | { 288 | QReadLocker oLock(&m_oMutex); 289 | 290 | if(m_bPowerEnabled) 291 | { 292 | m_pPowerPlotWidget->addData(qvvfPlotData, m_pStreamInterpreter->getLastHeader().getTimestamp_us(), qvu32PowerLRChanList); 293 | } 294 | 295 | if(m_bStokesPhaseEnabled) 296 | { 297 | m_pStokesPhasePlotWidget->addData(qvvfPlotData, m_pStreamInterpreter->getLastHeader().getTimestamp_us(), qvu32StokesPhaseQUChanList); 298 | } 299 | 300 | if(m_bBandPowerEnabled) 301 | { 302 | m_pBandPowerPlotWidget->addData(qvvfPlotData, m_pStreamInterpreter->getLastHeader().getTimestamp_us()); 303 | } 304 | 305 | break; 306 | } 307 | 308 | default: 309 | { 310 | } 311 | 312 | } 313 | } 314 | } 315 | } 316 | 317 | void cPlotsWidget::updatePlotType(uint16_t u16PlotType) 318 | { 319 | //Only use lowest 4 bits 320 | u16PlotType = 0x000F & u16PlotType; 321 | 322 | //If the plot is the same do nothing 323 | if(m_u16PlotType == u16PlotType) 324 | return; 325 | 326 | //Otherwise update 327 | switch(u16PlotType) 328 | { 329 | case AVN::Spectrometer::WB_SPECTROMETER_LRQU: 330 | { 331 | m_pUI->groupBox_stokesPhase->setTitle(QString("Stokes Q / U")); 332 | 333 | m_pPowerPlotWidget->setTitle(QString("WB Spectrometer - Relative Power - LCP / RCP")); 334 | m_pPowerPlotWidget->setYLabel(QString("Relative Power")); 335 | m_pPowerPlotWidget->setYUnit(QString("dB")); 336 | m_pPowerPlotWidget->setXLabel(QString("Frequency")); 337 | m_pPowerPlotWidget->setXUnit(QString("MHz")); 338 | QVector qvqstrCurveNames; 339 | qvqstrCurveNames.push_back(QString("LCP ")); 340 | qvqstrCurveNames.push_back(QString("RCP ")); 341 | m_pPowerPlotWidget->setCurveNames(qvqstrCurveNames); 342 | 343 | m_pStokesPhasePlotWidget->setTitle(QString("WB Spectrometer - Stokes Q / U")); 344 | m_pStokesPhasePlotWidget->setYLabel(QString("Power")); 345 | m_pStokesPhasePlotWidget->setYUnit(QString("")); 346 | m_pStokesPhasePlotWidget->setXLabel(QString("Frequency")); 347 | m_pStokesPhasePlotWidget->setXUnit(QString("MHz")); 348 | qvqstrCurveNames.clear(); 349 | qvqstrCurveNames.push_back(QString("Stokes Q")); 350 | qvqstrCurveNames.push_back(QString("Stokes U")); 351 | m_pStokesPhasePlotWidget->setCurveNames(qvqstrCurveNames); 352 | 353 | m_pBandPowerPlotWidget->setTitle(QString("Band Power Density - L, R, Q, U")); 354 | m_pBandPowerPlotWidget->setYLabel(QString("Power Density")); 355 | m_pBandPowerPlotWidget->setYUnit(QString("counts/MHz")); 356 | m_pBandPowerPlotWidget->setXLabel(QString("Timestamp")); 357 | m_pBandPowerPlotWidget->setXUnit(QString("")); 358 | m_pBandPowerPlotWidget->setSpanLengthControlScalingFactor(1.0, QString("s")); 359 | qvqstrCurveNames.clear(); 360 | qvqstrCurveNames.push_back(QString("LCP")); 361 | qvqstrCurveNames.push_back(QString("RCP")); 362 | qvqstrCurveNames.push_back(QString("Stokes Q")); 363 | qvqstrCurveNames.push_back(QString("Stokes U")); 364 | m_pBandPowerPlotWidget->setCurveNames(qvqstrCurveNames); 365 | 366 | m_pStokesPhasePlotWidget->setXSpan(0.0, 400.0); 367 | m_pPowerPlotWidget->setXSpan(0.0, 400.0); 368 | m_pBandPowerPlotWidget->setSelectableBand(0.0, 400.0, QString("MHz")); 369 | 370 | m_pPowerPlotWidget->enableLogConversion(true); 371 | //m_pBandPowerPlotWidget->enableLogConversion(true); 372 | m_pBandPowerPlotWidget->enableLogConversion(false); 373 | 374 | m_pPowerPlotWidget->enableRejectData(false); 375 | m_pStokesPhasePlotWidget->enableRejectData(false); 376 | m_pBandPowerPlotWidget->enableRejectData(false); 377 | 378 | cout << "cPlotsWidget::updatePlotType(): Setup plotting for Wideband Spectrometer LRQU" << endl; 379 | break; 380 | } 381 | 382 | case AVN::Spectrometer::WB_SPECTROMETER_LRPP: 383 | { 384 | m_pUI->groupBox_stokesPhase->setTitle(QString("Relative Phase")); 385 | 386 | m_pPowerPlotWidget->setTitle(QString("WB Spectrometer - Relative Power - LCP / RCP")); 387 | m_pPowerPlotWidget->setYLabel(QString("Relative Power")); 388 | m_pPowerPlotWidget->setYUnit(QString("dB")); 389 | m_pPowerPlotWidget->setXLabel(QString("Frequency")); 390 | m_pPowerPlotWidget->setXUnit(QString("MHz")); 391 | QVector qvqstrCurveNames; 392 | qvqstrCurveNames.push_back(QString("LCP")); 393 | qvqstrCurveNames.push_back(QString("RCP")); 394 | m_pPowerPlotWidget->setCurveNames(qvqstrCurveNames); 395 | 396 | m_pStokesPhasePlotWidget->setTitle(QString("WB Spectrometer - Relative Phase - LCP / RCP")); 397 | m_pStokesPhasePlotWidget->setYLabel(QString("Relative Phase")); 398 | m_pStokesPhasePlotWidget->setYUnit(QString("rad")); 399 | m_pStokesPhasePlotWidget->setXLabel(QString("Frequency")); 400 | m_pStokesPhasePlotWidget->setXUnit(QString("MHz")); 401 | qvqstrCurveNames.clear(); 402 | qvqstrCurveNames.push_back(QString("Relative Phase")); 403 | m_pStokesPhasePlotWidget->setCurveNames(qvqstrCurveNames); 404 | 405 | m_pBandPowerPlotWidget->setTitle(QString("Band Power Density - LCP, RCP")); 406 | m_pBandPowerPlotWidget->setYLabel(QString("Power Density")); 407 | //m_pBandPowerPlotWidget->setYUnit(QString("dB/MHz")); 408 | m_pBandPowerPlotWidget->setYUnit(QString("counts/MHz")); 409 | m_pBandPowerPlotWidget->setXLabel(QString("Timestamp")); 410 | m_pBandPowerPlotWidget->setXUnit(QString("")); 411 | m_pBandPowerPlotWidget->setSpanLengthControlScalingFactor(1.0, QString("s")); 412 | qvqstrCurveNames.clear(); 413 | qvqstrCurveNames.push_back(QString("LCP")); 414 | qvqstrCurveNames.push_back(QString("RCP")); 415 | m_pBandPowerPlotWidget->setCurveNames(qvqstrCurveNames); 416 | 417 | m_pStokesPhasePlotWidget->setXSpan(0.0, 400.0); 418 | m_pPowerPlotWidget->setXSpan(0.0, 400.0); 419 | m_pBandPowerPlotWidget->setSelectableBand(0.0, 400.0, QString("MHz")); 420 | 421 | m_pPowerPlotWidget->enableLogConversion(true); 422 | //m_pBandPowerPlotWidget->enableLogConversion(true); 423 | m_pBandPowerPlotWidget->enableLogConversion(false); 424 | 425 | m_pPowerPlotWidget->enableRejectData(false); 426 | m_pStokesPhasePlotWidget->enableRejectData(false); 427 | m_pBandPowerPlotWidget->enableRejectData(false); 428 | 429 | cout << "cPlotsWidget::updatePlotType(): Setup plotting for Wideband Spectrometer complex FFT data" << endl; 430 | 431 | break; 432 | } 433 | 434 | case AVN::Spectrometer::NB_SPECTROMETER_LRQU: 435 | { 436 | m_pUI->groupBox_stokesPhase->setTitle(QString("Stokes Q / U")); 437 | 438 | m_pPowerPlotWidget->setTitle(QString("NB Spectrometer - Relative Power - LCP / RCP")); 439 | m_pPowerPlotWidget->setYLabel(QString("Relative Power")); 440 | m_pPowerPlotWidget->setYUnit(QString("dB")); 441 | m_pPowerPlotWidget->setXLabel(QString("Frequency")); 442 | m_pPowerPlotWidget->setXUnit(QString("kHz")); 443 | QVector qvqstrCurveNames; 444 | qvqstrCurveNames.push_back(QString("LCP")); 445 | qvqstrCurveNames.push_back(QString("RCP")); 446 | m_pPowerPlotWidget->setCurveNames(qvqstrCurveNames); 447 | 448 | m_pStokesPhasePlotWidget->setTitle(QString("NB Spectrometer - Stokes Q / U")); 449 | m_pStokesPhasePlotWidget->setYLabel(QString("Relative Power")); 450 | m_pStokesPhasePlotWidget->setYUnit(QString("")); 451 | m_pStokesPhasePlotWidget->setXLabel(QString("Frequency")); 452 | m_pStokesPhasePlotWidget->setXUnit(QString("kHz")); 453 | qvqstrCurveNames.clear(); 454 | qvqstrCurveNames.push_back(QString("Stokes Q")); 455 | qvqstrCurveNames.push_back(QString("Stokes U")); 456 | m_pStokesPhasePlotWidget->setCurveNames(qvqstrCurveNames); 457 | 458 | m_pBandPowerPlotWidget->setTitle(QString("Band Power Density - LCP, RCP, Q, U")); 459 | m_pBandPowerPlotWidget->setYLabel(QString("Power Density")); 460 | //m_pBandPowerPlotWidget->setYUnit(QString("dB/kHz")); 461 | m_pBandPowerPlotWidget->setYUnit(QString("counts/kHz")); 462 | m_pBandPowerPlotWidget->setXLabel(QString("Timestamp")); 463 | m_pBandPowerPlotWidget->setXUnit(QString("")); 464 | m_pBandPowerPlotWidget->setSpanLengthControlScalingFactor(1.0, QString("s")); 465 | qvqstrCurveNames.clear(); 466 | qvqstrCurveNames.push_back(QString("LCP")); 467 | qvqstrCurveNames.push_back(QString("RCP")); 468 | qvqstrCurveNames.push_back(QString("Stokes Q")); 469 | qvqstrCurveNames.push_back(QString("Stokes U")); 470 | m_pBandPowerPlotWidget->setCurveNames(qvqstrCurveNames); 471 | 472 | m_pStokesPhasePlotWidget->setXSpan(-781.25, 781.25); 473 | m_pPowerPlotWidget->setXSpan(-781.25, 781.25); 474 | m_pBandPowerPlotWidget->setSelectableBand(-781.25, 781.25, QString("kHz")); 475 | 476 | m_pPowerPlotWidget->enableLogConversion(true); 477 | //m_pBandPowerPlotWidget->enableLogConversion(true); 478 | m_pBandPowerPlotWidget->enableLogConversion(false); 479 | 480 | m_pPowerPlotWidget->enableRejectData(false); 481 | m_pStokesPhasePlotWidget->enableRejectData(false); 482 | m_pBandPowerPlotWidget->enableRejectData(false); 483 | 484 | cout << "cPlotsWidget::updatePlotType(): Setup plotting for Narrowband Spectrometer LRQU" << endl; 485 | break; 486 | } 487 | 488 | case AVN::Spectrometer::NB_SPECTROMETER_LRPP: 489 | { 490 | m_pUI->groupBox_stokesPhase->setTitle(QString("Relative Phase")); 491 | 492 | m_pPowerPlotWidget->setTitle(QString("NB Spectrometer - Relative Power - LCP / RCP")); 493 | m_pPowerPlotWidget->setYLabel(QString("Relative Power")); 494 | m_pPowerPlotWidget->setYUnit(QString("dB")); 495 | m_pPowerPlotWidget->setXLabel(QString("Frequency")); 496 | m_pPowerPlotWidget->setXUnit(QString("kHz")); 497 | QVector qvqstrCurveNames; 498 | qvqstrCurveNames.push_back(QString("LCP")); 499 | qvqstrCurveNames.push_back(QString("RCP")); 500 | m_pPowerPlotWidget->setCurveNames(qvqstrCurveNames); 501 | 502 | m_pStokesPhasePlotWidget->setTitle(QString("NB Spectrometer - Relative Phase")); 503 | m_pStokesPhasePlotWidget->setYLabel(QString("Relative Phase")); 504 | m_pStokesPhasePlotWidget->setYUnit(QString("rad")); 505 | m_pStokesPhasePlotWidget->setXLabel(QString("Frequency")); 506 | m_pStokesPhasePlotWidget->setXUnit(QString("kHz")); 507 | qvqstrCurveNames.clear(); 508 | qvqstrCurveNames.push_back(QString("Relative Phase")); 509 | m_pStokesPhasePlotWidget->setCurveNames(qvqstrCurveNames); 510 | 511 | m_pBandPowerPlotWidget->setTitle(QString("Band Power Density - LCP, RCP")); 512 | m_pBandPowerPlotWidget->setYLabel(QString("Power Density")); 513 | //m_pBandPowerPlotWidget->setYUnit(QString("dB/kHz")); 514 | m_pBandPowerPlotWidget->setYUnit(QString("counts/kHz")); 515 | m_pBandPowerPlotWidget->setXLabel(QString("Timestamp")); 516 | m_pBandPowerPlotWidget->setXUnit(QString("")); 517 | m_pBandPowerPlotWidget->setSpanLengthControlScalingFactor(1.0, QString("s")); 518 | qvqstrCurveNames.clear(); 519 | qvqstrCurveNames.push_back(QString("LCP")); 520 | qvqstrCurveNames.push_back(QString("RCP")); 521 | m_pBandPowerPlotWidget->setCurveNames(qvqstrCurveNames); 522 | 523 | m_pStokesPhasePlotWidget->setXSpan(-781.25, 781.25); 524 | m_pPowerPlotWidget->setXSpan(-781.25, 781.25); 525 | m_pBandPowerPlotWidget->setSelectableBand(-781.25, 781.25, QString("kHz")); 526 | 527 | m_pPowerPlotWidget->enableLogConversion(true); 528 | //m_pBandPowerPlotWidget->enableLogConversion(true); 529 | m_pBandPowerPlotWidget->enableLogConversion(false); 530 | 531 | m_pPowerPlotWidget->enableRejectData(false); 532 | m_pStokesPhasePlotWidget->enableRejectData(false); 533 | m_pBandPowerPlotWidget->enableRejectData(false); 534 | cout << "cPlotsWidget::updatePlotType(): Setup plotting for Narrowband Spectrometer complex FFT data" << endl; 535 | break; 536 | } 537 | 538 | 539 | default: 540 | { 541 | m_pPowerPlotWidget->setTitle(QString("Received unknown plot type: %1").arg(u16PlotType)); 542 | m_pStokesPhasePlotWidget->setTitle(QString("Received unknown plot type: %1").arg(u16PlotType)); 543 | m_pBandPowerPlotWidget->setTitle(QString("Received unknown plot type: %1").arg(u16PlotType)); 544 | 545 | QVector qvqstrCurveNames; 546 | m_pPowerPlotWidget->setCurveNames(qvqstrCurveNames); 547 | m_pStokesPhasePlotWidget->setCurveNames(qvqstrCurveNames); 548 | m_pBandPowerPlotWidget->setCurveNames(qvqstrCurveNames); 549 | 550 | m_pPowerPlotWidget->enableRejectData(true); 551 | m_pStokesPhasePlotWidget->enableRejectData(true); 552 | m_pBandPowerPlotWidget->enableRejectData(true); 553 | 554 | cout << "cPlotsWidget::updatePlotType(): Warning got unknown plot type " << u16PlotType << ". Will not plot data" << endl; 555 | break; 556 | } 557 | 558 | } 559 | 560 | //Store the current plot type 561 | m_u16PlotType = u16PlotType; 562 | 563 | //Strobe auto scale: 564 | m_pPowerPlotWidget->strobeAutoscale(100); 565 | m_pStokesPhasePlotWidget->strobeAutoscale(100); 566 | 567 | m_pBandPowerPlotWidget->resetHistory(); 568 | m_pBandPowerPlotWidget->strobeAutoscale(5000); 569 | } 570 | 571 | void cPlotsWidget::slotPowerPlotEnabled(bool bEnabled) 572 | { 573 | m_pPowerPlotWidget->setVisible(bEnabled); 574 | 575 | QWriteLocker oLock(&m_oMutex); 576 | m_bPowerEnabled = bEnabled; 577 | 578 | sigPowerPlotEnabled(bEnabled); 579 | } 580 | 581 | void cPlotsWidget::slotStokesPhasePlotEnabled(bool bEnabled) 582 | { 583 | m_pStokesPhasePlotWidget->setVisible(bEnabled); 584 | 585 | QWriteLocker oLock(&m_oMutex); 586 | m_bStokesPhaseEnabled = bEnabled; 587 | 588 | sigStokesPhasePlotEnabled(bEnabled); 589 | } 590 | 591 | void cPlotsWidget::slotBandPowerPlotEnabled(bool bEnabled) 592 | { 593 | m_pBandPowerPlotWidget->setVisible(bEnabled); 594 | 595 | QWriteLocker oLock(&m_oMutex); 596 | m_bBandPowerEnabled = bEnabled; 597 | 598 | //Remove band lines from the power plot while the band power power is hidden 599 | m_pPowerPlotWidget->slotShowVerticalLines(bEnabled); 600 | 601 | sigBandPowerPlotEnabled(bEnabled); 602 | } 603 | 604 | void cPlotsWidget::socketConnected_callback() 605 | { 606 | sigConnected(); 607 | sigConnected(true); 608 | } 609 | 610 | void cPlotsWidget::socketDisconnected_callback() 611 | { 612 | setIsRunning(false); 613 | 614 | sigDisconnect(); //Queued connection to slotDisconnect in this class. 615 | //This will be called by the socket reading thread. so it needs to be decoupled with a queued connection 616 | //The slotDisconnect asked the socket reading thread to join so this queued connection prevents the socket 617 | //reading thread from joining itself. 618 | } 619 | 620 | void cPlotsWidget::accumulationLength_callback(int64_t i64Timestamp_us, uint32_t u32NFrames) 621 | { 622 | //Update accumulation length 623 | 624 | QWriteLocker oLock(&m_oMutex); 625 | 626 | m_u32AccumulationLength_nFrames = u32NFrames; 627 | } 628 | 629 | void cPlotsWidget::slotEnablePowerPlot(bool bEnable) 630 | { 631 | blockSignals(true); //Don't notify change to other classes and the request came from outside this class 632 | 633 | m_pUI->groupBox_powers->setChecked(bEnable); 634 | slotPowerPlotEnabled(bEnable); 635 | 636 | blockSignals(false); 637 | } 638 | 639 | void cPlotsWidget::slotEnableStokesPhasePlot(bool bEnable) 640 | { 641 | blockSignals(true); 642 | 643 | m_pUI->groupBox_stokesPhase->setChecked(bEnable); 644 | slotStokesPhasePlotEnabled(bEnable); 645 | 646 | blockSignals(false); 647 | } 648 | 649 | void cPlotsWidget::slotEnableBandPowerPlot(bool bEnable) 650 | { 651 | blockSignals(true); 652 | 653 | m_pUI->groupBox_bandPower->setChecked(bEnable); 654 | slotBandPowerPlotEnabled(bEnable); 655 | 656 | blockSignals(false); 657 | } 658 | -------------------------------------------------------------------------------- /RoachAcquisitionServerKATCPClient.cpp: -------------------------------------------------------------------------------- 1 | //System includes 2 | 3 | //Library includes 4 | 5 | //Local includes 6 | #include "RoachAcquisitionServerKATCPClient.h" 7 | 8 | using namespace std; 9 | 10 | cRoachAcquisitionServerKATCPClient::cRoachAcquisitionServerKATCPClient() : 11 | cKATCPClientBase() 12 | { 13 | } 14 | 15 | cRoachAcquisitionServerKATCPClient::~cRoachAcquisitionServerKATCPClient() 16 | { 17 | } 18 | 19 | void cRoachAcquisitionServerKATCPClient::onConnected() 20 | { 21 | //Request the current recording status. 22 | requestRecordingStatus(); 23 | 24 | //Subscribe to the necessary sensors 25 | subscribeToSensors(); 26 | 27 | //Ask for an updated list of Firmware launchers 28 | requestRoachGatewareList(); 29 | } 30 | 31 | void cRoachAcquisitionServerKATCPClient::processKATCPMessage(const vector &vstrTokens) 32 | { 33 | // cout << "Got KATCP message: "; 34 | // for(uint32_t ui = 0; ui < vstrTokens.size(); ui++ ) 35 | // { 36 | // cout << vstrTokens[ui] << " "; 37 | // } 38 | // cout << endl; 39 | 40 | if( !vstrTokens[0].compare("#recordingStopped") ) 41 | { 42 | sendRecordingStopped(); 43 | return; 44 | } 45 | 46 | 47 | 48 | if(!vstrTokens[0].compare("#recordingStarted")) 49 | { 50 | cout <<"Sending recording started" << endl; 51 | sendRecordingStarted(); 52 | return; 53 | } 54 | 55 | 56 | if(!vstrTokens[0].compare("#recordingInfo")) 57 | { 58 | if(vstrTokens.size() < 8) 59 | return; 60 | 61 | int64_t i64StartTime_us = strtoll(vstrTokens[2].c_str(), NULL, 10); 62 | int64_t i64EllapsedTime_us = strtoll(vstrTokens[3].c_str(), NULL, 10); 63 | int64_t i64StopTime_us = strtoll(vstrTokens[4].c_str(), NULL, 10); 64 | int64_t i64TimeLeft_us = strtoll(vstrTokens[5].c_str(), NULL, 10); 65 | uint64_t u64CurrentFileSize_B = strtoull(vstrTokens[6].c_str(), NULL, 10); 66 | uint64_t u64DiskSpaceRemaining_B = strtoull(vstrTokens[7].c_str(), NULL, 10); 67 | 68 | sendRecordingInfoUpdate(vstrTokens[1], i64StartTime_us, i64EllapsedTime_us, i64StopTime_us, i64TimeLeft_us, u64CurrentFileSize_B, u64DiskSpaceRemaining_B); 69 | 70 | return; 71 | } 72 | 73 | 74 | if(!vstrTokens[0].compare("#roachGatewareList")) 75 | { 76 | vector vstrGatewareList(vstrTokens); 77 | vstrGatewareList.erase(vstrGatewareList.begin()); 78 | 79 | sendRoachGatewareList(vstrGatewareList); 80 | 81 | return; 82 | } 83 | 84 | 85 | //Sensors 86 | 87 | if(!vstrTokens[0].compare("#sensor-status")) 88 | { 89 | if(vstrTokens.size() < 6) 90 | return; 91 | 92 | int64_t i64Timestamp_us = strtoll(vstrTokens[1].c_str(), NULL, 10); 93 | 94 | if(!vstrTokens[3].compare("stationControllerConnected")) 95 | { 96 | sendStationControllerKATCPConnected( (bool)(0x00000001 & strtol(vstrTokens[5].c_str(), NULL, 10)) ); 97 | return; 98 | } 99 | 100 | if(!vstrTokens[3].compare("actualAntennaAz")) 101 | { 102 | sendActualAntennaAz(i64Timestamp_us, strtod(vstrTokens[5].c_str(), NULL) ); 103 | return; 104 | } 105 | 106 | if(!vstrTokens[3].compare("actualAntennaEl")) 107 | { 108 | sendActualAntennaEl(i64Timestamp_us, strtod(vstrTokens[5].c_str(), NULL) ); 109 | return; 110 | } 111 | 112 | if(!vstrTokens[3].compare("actualSourceOffsetAz")) 113 | { 114 | sendActualSourceOffsetAz(i64Timestamp_us, strtod(vstrTokens[5].c_str(), NULL) ); 115 | return; 116 | } 117 | 118 | if(!vstrTokens[3].compare("actualSourceOffsetEl")) 119 | { 120 | sendActualSourceOffsetEl(i64Timestamp_us, strtod(vstrTokens[5].c_str(), NULL) ); 121 | return; 122 | } 123 | 124 | if(!vstrTokens[3].compare("frequencyRFChan0")) 125 | { 126 | sendFrequencyRFChan0(i64Timestamp_us, strtod(vstrTokens[5].c_str(), NULL) ); 127 | return; 128 | } 129 | 130 | if(!vstrTokens[3].compare("frequencyRFChan1")) 131 | { 132 | sendFrequencyRFChan1(i64Timestamp_us, strtod(vstrTokens[5].c_str(), NULL) ); 133 | return; 134 | } 135 | 136 | if(!vstrTokens[3].compare("roachConnected")) 137 | { 138 | sendRoachKATCPConnected( (bool)(0x00000001 & strtol(vstrTokens[5].c_str(), NULL, 10)) ); 139 | return; 140 | } 141 | 142 | if(!vstrTokens[3].compare("roachStokesEnabled")) 143 | { 144 | sendStokesEnabled( (bool)(0x00000001 & strtol(vstrTokens[5].c_str(), NULL, 10)) ); 145 | return; 146 | } 147 | 148 | if(!vstrTokens[3].compare("roachAccumulationLength")) 149 | { 150 | sendAccumulationLength(i64Timestamp_us, strtol(vstrTokens[5].c_str(), NULL, 10)); 151 | return; 152 | } 153 | 154 | if(!vstrTokens[3].compare("roachCoarseChannelSelect")) 155 | { 156 | sendCoarseChannelSelect(i64Timestamp_us, strtol(vstrTokens[5].c_str(), NULL, 10)); 157 | return; 158 | } 159 | 160 | if(!vstrTokens[3].compare("roachFrequencyFs")) 161 | { 162 | sendFrequencyFs(strtod(vstrTokens[5].c_str(), NULL)); 163 | return; 164 | } 165 | 166 | if(!vstrTokens[3].compare("roachSizeOfCoarseFFT")) 167 | { 168 | sendSizeOfCoarseFFT(strtol(vstrTokens[5].c_str(), NULL, 10)); 169 | return; 170 | } 171 | 172 | if(!vstrTokens[3].compare("roachSizeOfFineFFT")) 173 | { 174 | sendSizeOfFineFFT(strtol(vstrTokens[5].c_str(), NULL, 10)); 175 | return; 176 | } 177 | 178 | if(!vstrTokens[3].compare("roachCoarseFFTShiftMask")) 179 | { 180 | sendCoarseFFTShiftMask(i64Timestamp_us, strtol(vstrTokens[5].c_str(), NULL, 10)); 181 | return; 182 | } 183 | 184 | if(!vstrTokens[3].compare("roachAttenuationADCChan0")) 185 | { 186 | sendAttenuationADCChan0(i64Timestamp_us, strtod(vstrTokens[5].c_str(), NULL)); 187 | return; 188 | } 189 | 190 | if(!vstrTokens[3].compare("roachAttenuationADCChan1")) 191 | { 192 | sendAttenuationADCChan1(i64Timestamp_us, strtod(vstrTokens[5].c_str(), NULL)); 193 | return; 194 | } 195 | 196 | if(!vstrTokens[3].compare("roachNoiseDiodeEnabled")) 197 | { 198 | sendNoiseDiodeEnabled(i64Timestamp_us, (bool)(0x00000001 & strtol(vstrTokens[5].c_str(), NULL, 10))); 199 | return; 200 | } 201 | 202 | if(!vstrTokens[3].compare("roachNoiseDiodeDutyCycleEnabled")) 203 | { 204 | sendNoiseDiodeDutyCycleEnabled(i64Timestamp_us, (bool)(0x00000001 & strtol(vstrTokens[5].c_str(), NULL, 10))); 205 | return; 206 | } 207 | 208 | if(!vstrTokens[3].compare("roachNoiseDiodeDutyCycleOnDuration")) 209 | { 210 | sendNoiseDiodeDutyCycleOnDuration(i64Timestamp_us, strtol(vstrTokens[5].c_str(), NULL, 10)); 211 | return; 212 | } 213 | 214 | if(!vstrTokens[3].compare("roachNoiseDiodeDutyCycleOffDuration")) 215 | { 216 | sendNoiseDiodeDutyCycleOffDuration(i64Timestamp_us, strtol(vstrTokens[5].c_str(), NULL, 10)); 217 | return; 218 | } 219 | 220 | if(!vstrTokens[3].compare("roachOverflowRegs")) 221 | { 222 | sendOverflowsRegs(i64Timestamp_us, strtol(vstrTokens[5].c_str(), NULL, 10)); 223 | return; 224 | } 225 | 226 | if(!vstrTokens[3].compare("roachEth10GbEUp")) 227 | { 228 | sendEth10GbEUp(i64Timestamp_us, (bool)(0x00000001 & strtol(vstrTokens[5].c_str(), NULL, 10))); 229 | return; 230 | } 231 | 232 | if(!vstrTokens[3].compare("roachPPSCount")) 233 | { 234 | sendPPSCount(i64Timestamp_us, strtol(vstrTokens[5].c_str(), NULL, 10)); 235 | return; 236 | } 237 | 238 | if(!vstrTokens[3].compare("roachClockFrequency")) 239 | { 240 | sendClockFrequency(i64Timestamp_us, strtol(vstrTokens[5].c_str(), NULL, 10)); 241 | return; 242 | } 243 | } 244 | 245 | // cout << "cRoachAcquisitionServerKATCPClient::processKATCPMessage(): Ignoring KATCP message: "; 246 | // for(uint32_t ui = 0; ui < vstrTokens.size(); ui++ ) 247 | // { 248 | // cout << vstrTokens[ui] << " "; 249 | // } 250 | // cout << endl; 251 | } 252 | 253 | void cRoachAcquisitionServerKATCPClient::sendStationControllerKATCPConnected(bool bConnected) 254 | { 255 | boost::shared_lock oLock; 256 | 257 | //Note the vector contains the base type callback handler pointer so cast to the derived version is this class 258 | //to call function added in the derived version of the callback handler interface class 259 | 260 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers.size(); ui++) 261 | { 262 | cCallbackInterface *pHandler = dynamic_cast(m_vpCallbackHandlers[ui]); 263 | pHandler->stationControllerKATCPConnected_callback(bConnected); 264 | } 265 | 266 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers_shared.size(); ui++) 267 | { 268 | boost::shared_ptr pHandler = boost::dynamic_pointer_cast(m_vpCallbackHandlers_shared[ui]); 269 | pHandler->stationControllerKATCPConnected_callback(bConnected); 270 | } 271 | } 272 | 273 | void cRoachAcquisitionServerKATCPClient::sendRecordingStarted() 274 | { 275 | boost::shared_lock oLock; 276 | 277 | //Note the vector contains the base type callback handler pointer so cast to the derived version is this class 278 | //to call function added in the derived version of the callback handler interface class 279 | 280 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers.size(); ui++) 281 | { 282 | cCallbackInterface *pHandler = dynamic_cast(m_vpCallbackHandlers[ui]); 283 | pHandler->recordingStarted_callback(); 284 | } 285 | 286 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers_shared.size(); ui++) 287 | { 288 | boost::shared_ptr pHandler = boost::dynamic_pointer_cast(m_vpCallbackHandlers_shared[ui]); 289 | pHandler->recordingStarted_callback(); 290 | } 291 | } 292 | 293 | void cRoachAcquisitionServerKATCPClient::sendRecordingStopped() 294 | { 295 | boost::shared_lock oLock; 296 | 297 | //Note the vector contains the base type callback handler pointer so cast to the derived version is this class 298 | //to call function added in the derived version of the callback handler interface class 299 | 300 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers.size(); ui++) 301 | { 302 | cCallbackInterface *pHandler = dynamic_cast(m_vpCallbackHandlers[ui]); 303 | pHandler->recordingStopped_callback(); 304 | } 305 | 306 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers_shared.size(); ui++) 307 | { 308 | boost::shared_ptr pHandler = boost::dynamic_pointer_cast(m_vpCallbackHandlers_shared[ui]); 309 | pHandler->recordingStopped_callback(); 310 | } 311 | } 312 | 313 | void cRoachAcquisitionServerKATCPClient::sendRecordingInfoUpdate(const string &strFilename, 314 | int64_t i64StartTime_us, int64_t i64EllapsedTime_us, 315 | int64_t i64StopTime_us, int64_t i64TimeLeft_us, 316 | uint64_t u64CurrentFileSize_B, uint64_t u64DiskSpaceRemaining_B) 317 | { 318 | boost::shared_lock oLock; 319 | 320 | //Note the vector contains the base type callback handler pointer so cast to the derived version is this class 321 | //to call function added in the derived version of the callback handler interface class 322 | 323 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers.size(); ui++) 324 | { 325 | cCallbackInterface *pHandler = dynamic_cast(m_vpCallbackHandlers[ui]); 326 | pHandler->recordingInfoUpdate_callback(strFilename, i64StartTime_us, i64EllapsedTime_us, i64StopTime_us, i64TimeLeft_us, u64CurrentFileSize_B, u64DiskSpaceRemaining_B); 327 | } 328 | 329 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers_shared.size(); ui++) 330 | { 331 | boost::shared_ptr pHandler = boost::dynamic_pointer_cast(m_vpCallbackHandlers_shared[ui]); 332 | pHandler->recordingInfoUpdate_callback(strFilename, i64StartTime_us, i64EllapsedTime_us, i64StopTime_us, i64TimeLeft_us, u64CurrentFileSize_B, u64DiskSpaceRemaining_B); 333 | } 334 | } 335 | 336 | void cRoachAcquisitionServerKATCPClient::sendActualAntennaAz(int64_t i64Timestamp_us,double dAzimuth_deg) 337 | { 338 | boost::shared_lock oLock; 339 | 340 | //Note the vector contains the base type callback handler pointer so cast to the derived version is this class 341 | //to call function added in the derived version of the callback handler interface class 342 | 343 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers.size(); ui++) 344 | { 345 | cCallbackInterface *pHandler = dynamic_cast(m_vpCallbackHandlers[ui]); 346 | pHandler->actualAntennaAz_callback(i64Timestamp_us, dAzimuth_deg); 347 | } 348 | 349 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers_shared.size(); ui++) 350 | { 351 | boost::shared_ptr pHandler = boost::dynamic_pointer_cast(m_vpCallbackHandlers_shared[ui]); 352 | pHandler->actualAntennaAz_callback(i64Timestamp_us, dAzimuth_deg); 353 | } 354 | } 355 | 356 | void cRoachAcquisitionServerKATCPClient::sendActualAntennaEl(int64_t i64Timestamp_us,double dElevation_deg) 357 | { 358 | boost::shared_lock oLock; 359 | 360 | //Note the vector contains the base type callback handler pointer so cast to the derived version is this class 361 | //to call function added in the derived version of the callback handler interface class 362 | 363 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers.size(); ui++) 364 | { 365 | cCallbackInterface *pHandler = dynamic_cast(m_vpCallbackHandlers[ui]); 366 | pHandler->actualAntennaEl_callback(i64Timestamp_us, dElevation_deg); 367 | } 368 | 369 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers_shared.size(); ui++) 370 | { 371 | boost::shared_ptr pHandler = boost::dynamic_pointer_cast(m_vpCallbackHandlers_shared[ui]); 372 | pHandler->actualAntennaEl_callback(i64Timestamp_us, dElevation_deg); 373 | } 374 | } 375 | 376 | void cRoachAcquisitionServerKATCPClient::sendActualSourceOffsetAz(int64_t i64Timestamp_us, double dAzimuthOffset_deg) 377 | { 378 | boost::shared_lock oLock; 379 | 380 | //Note the vector contains the base type callback handler pointer so cast to the derived version is this class 381 | //to call function added in the derived version of the callback handler interface class 382 | 383 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers.size(); ui++) 384 | { 385 | cCallbackInterface *pHandler = dynamic_cast(m_vpCallbackHandlers[ui]); 386 | pHandler->actualSourceOffsetAz_callback(i64Timestamp_us, dAzimuthOffset_deg); 387 | } 388 | 389 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers_shared.size(); ui++) 390 | { 391 | boost::shared_ptr pHandler = boost::dynamic_pointer_cast(m_vpCallbackHandlers_shared[ui]); 392 | pHandler->actualSourceOffsetAz_callback(i64Timestamp_us, dAzimuthOffset_deg); 393 | } 394 | } 395 | 396 | void cRoachAcquisitionServerKATCPClient::sendActualSourceOffsetEl(int64_t i64Timestamp_us, double dElevationOffset_deg) 397 | { 398 | boost::shared_lock oLock; 399 | 400 | //Note the vector contains the base type callback handler pointer so cast to the derived version is this class 401 | //to call function added in the derived version of the callback handler interface class 402 | 403 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers.size(); ui++) 404 | { 405 | cCallbackInterface *pHandler = dynamic_cast(m_vpCallbackHandlers[ui]); 406 | pHandler->actualSourceOffsetEl_callback(i64Timestamp_us, dElevationOffset_deg); 407 | } 408 | 409 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers_shared.size(); ui++) 410 | { 411 | boost::shared_ptr pHandler = boost::dynamic_pointer_cast(m_vpCallbackHandlers_shared[ui]); 412 | pHandler->actualSourceOffsetEl_callback(i64Timestamp_us, dElevationOffset_deg); 413 | } 414 | } 415 | 416 | void cRoachAcquisitionServerKATCPClient::sendFrequencyRFChan0(int64_t i64Timestamp_us, double dFreqencyRFChan0_MHz) 417 | { 418 | boost::shared_lock oLock; 419 | 420 | //Note the vector contains the base type callback handler pointer so cast to the derived version is this class 421 | //to call function added in the derived version of the callback handler interface class 422 | 423 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers.size(); ui++) 424 | { 425 | cCallbackInterface *pHandler = dynamic_cast(m_vpCallbackHandlers[ui]); 426 | pHandler->frequencyRFChan0_callback(i64Timestamp_us, dFreqencyRFChan0_MHz); 427 | } 428 | 429 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers_shared.size(); ui++) 430 | { 431 | boost::shared_ptr pHandler = boost::dynamic_pointer_cast(m_vpCallbackHandlers_shared[ui]); 432 | pHandler->frequencyRFChan0_callback(i64Timestamp_us, dFreqencyRFChan0_MHz); 433 | } 434 | } 435 | 436 | void cRoachAcquisitionServerKATCPClient::sendFrequencyRFChan1(int64_t i64Timestamp_us, double dFreqencyRFChan1_MHz) 437 | { 438 | boost::shared_lock oLock; 439 | 440 | //Note the vector contains the base type callback handler pointer so cast to the derived version is this class 441 | //to call function added in the derived version of the callback handler interface class 442 | 443 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers.size(); ui++) 444 | { 445 | cCallbackInterface *pHandler = dynamic_cast(m_vpCallbackHandlers[ui]); 446 | pHandler->frequencyRFChan1_callback(i64Timestamp_us, dFreqencyRFChan1_MHz); 447 | } 448 | 449 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers_shared.size(); ui++) 450 | { 451 | boost::shared_ptr pHandler = boost::dynamic_pointer_cast(m_vpCallbackHandlers_shared[ui]); 452 | pHandler->frequencyRFChan1_callback(i64Timestamp_us, dFreqencyRFChan1_MHz); 453 | } 454 | } 455 | 456 | void cRoachAcquisitionServerKATCPClient::sendRoachGatewareList(const vector &vstrGatewareList) 457 | { 458 | boost::shared_lock oLock; 459 | 460 | //Note the vector contains the base type callback handler pointer so cast to the derived version is this class 461 | //to call function added in the derived version of the callback handler interface class 462 | 463 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers.size(); ui++) 464 | { 465 | cCallbackInterface *pHandler = dynamic_cast(m_vpCallbackHandlers[ui]); 466 | pHandler->roachGatewareList_callback(vstrGatewareList); 467 | } 468 | 469 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers_shared.size(); ui++) 470 | { 471 | boost::shared_ptr pHandler = boost::dynamic_pointer_cast(m_vpCallbackHandlers_shared[ui]); 472 | pHandler->roachGatewareList_callback(vstrGatewareList); 473 | } 474 | } 475 | 476 | void cRoachAcquisitionServerKATCPClient::sendRoachKATCPConnected(bool bConnected) 477 | { 478 | boost::shared_lock oLock; 479 | 480 | //Note the vector contains the base type callback handler pointer so cast to the derived version is this class 481 | //to call function added in the derived version of the callback handler interface class 482 | 483 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers.size(); ui++) 484 | { 485 | cCallbackInterface *pHandler = dynamic_cast(m_vpCallbackHandlers[ui]); 486 | pHandler->roachKATCPConnected_callback(bConnected); 487 | } 488 | 489 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers_shared.size(); ui++) 490 | { 491 | boost::shared_ptr pHandler = boost::dynamic_pointer_cast(m_vpCallbackHandlers_shared[ui]); 492 | pHandler->roachKATCPConnected_callback(bConnected); 493 | } 494 | } 495 | 496 | void cRoachAcquisitionServerKATCPClient::sendStokesEnabled(bool bConnected) 497 | { 498 | boost::shared_lock oLock; 499 | 500 | //Note the vector contains the base type callback handler pointer so cast to the derived version is this class 501 | //to call function added in the derived version of the callback handler interface class 502 | 503 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers.size(); ui++) 504 | { 505 | cCallbackInterface *pHandler = dynamic_cast(m_vpCallbackHandlers[ui]); 506 | pHandler->stokesEnabled_callback(bConnected); 507 | } 508 | 509 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers_shared.size(); ui++) 510 | { 511 | boost::shared_ptr pHandler = boost::dynamic_pointer_cast(m_vpCallbackHandlers_shared[ui]); 512 | pHandler->stokesEnabled_callback(bConnected); 513 | } 514 | } 515 | 516 | void cRoachAcquisitionServerKATCPClient::sendAccumulationLength(int64_t i64Timestamp_us, uint32_t u32NFrames) 517 | { 518 | boost::shared_lock oLock; 519 | 520 | //Note the vector contains the base type callback handler pointer so cast to the derived version is this class 521 | //to call function added in the derived version of the callback handler interface class 522 | 523 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers.size(); ui++) 524 | { 525 | cCallbackInterface *pHandler = dynamic_cast(m_vpCallbackHandlers[ui]); 526 | pHandler->accumulationLength_callback(i64Timestamp_us, u32NFrames); 527 | } 528 | 529 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers_shared.size(); ui++) 530 | { 531 | boost::shared_ptr pHandler = boost::dynamic_pointer_cast(m_vpCallbackHandlers_shared[ui]); 532 | pHandler->accumulationLength_callback(i64Timestamp_us, u32NFrames); 533 | } 534 | } 535 | 536 | void cRoachAcquisitionServerKATCPClient::sendCoarseChannelSelect(int64_t i64Timestamp_us, uint32_t u32ChannelNo) 537 | { 538 | boost::shared_lock oLock; 539 | 540 | //Note the vector contains the base type callback handler pointer so cast to the derived version is this class 541 | //to call function added in the derived version of the callback handler interface class 542 | 543 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers.size(); ui++) 544 | { 545 | cCallbackInterface *pHandler = dynamic_cast(m_vpCallbackHandlers[ui]); 546 | pHandler->coarseChannelSelect_callback(i64Timestamp_us, u32ChannelNo); 547 | } 548 | 549 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers_shared.size(); ui++) 550 | { 551 | boost::shared_ptr pHandler = boost::dynamic_pointer_cast(m_vpCallbackHandlers_shared[ui]); 552 | pHandler->coarseChannelSelect_callback(i64Timestamp_us, u32ChannelNo); 553 | } 554 | } 555 | 556 | void cRoachAcquisitionServerKATCPClient::sendFrequencyFs(double dFrequencyFs_Hz) 557 | { 558 | boost::shared_lock oLock; 559 | 560 | //Note the vector contains the base type callback handler pointer so cast to the derived version is this class 561 | //to call function added in the derived version of the callback handler interface class 562 | 563 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers.size(); ui++) 564 | { 565 | cCallbackInterface *pHandler = dynamic_cast(m_vpCallbackHandlers[ui]); 566 | pHandler->frequencyFs_callback(dFrequencyFs_Hz); 567 | } 568 | 569 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers_shared.size(); ui++) 570 | { 571 | boost::shared_ptr pHandler = boost::dynamic_pointer_cast(m_vpCallbackHandlers_shared[ui]); 572 | pHandler->frequencyFs_callback(dFrequencyFs_Hz); 573 | } 574 | } 575 | 576 | void cRoachAcquisitionServerKATCPClient::sendSizeOfCoarseFFT(uint32_t u32SizeOfCoarseFFT_nSamp) 577 | { 578 | boost::shared_lock oLock; 579 | 580 | //Note the vector contains the base type callback handler pointer so cast to the derived version is this class 581 | //to call function added in the derived version of the callback handler interface class 582 | 583 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers.size(); ui++) 584 | { 585 | cCallbackInterface *pHandler = dynamic_cast(m_vpCallbackHandlers[ui]); 586 | pHandler->sizeOfCoarseFFT_callback(u32SizeOfCoarseFFT_nSamp); 587 | } 588 | 589 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers_shared.size(); ui++) 590 | { 591 | boost::shared_ptr pHandler = boost::dynamic_pointer_cast(m_vpCallbackHandlers_shared[ui]); 592 | pHandler->sizeOfCoarseFFT_callback(u32SizeOfCoarseFFT_nSamp); 593 | } 594 | } 595 | 596 | void cRoachAcquisitionServerKATCPClient::sendSizeOfFineFFT(uint32_t u32FineFFTSize_nSamp) 597 | { 598 | boost::shared_lock oLock; 599 | 600 | //Note the vector contains the base type callback handler pointer so cast to the derived version is this class 601 | //to call function added in the derived version of the callback handler interface class 602 | 603 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers.size(); ui++) 604 | { 605 | cCallbackInterface *pHandler = dynamic_cast(m_vpCallbackHandlers[ui]); 606 | pHandler->sizeOfFineFFT_callback(u32FineFFTSize_nSamp); 607 | } 608 | 609 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers_shared.size(); ui++) 610 | { 611 | boost::shared_ptr pHandler = boost::dynamic_pointer_cast(m_vpCallbackHandlers_shared[ui]); 612 | pHandler->sizeOfFineFFT_callback(u32FineFFTSize_nSamp); 613 | } 614 | } 615 | 616 | void cRoachAcquisitionServerKATCPClient::sendCoarseFFTShiftMask(int64_t i64Timestamp_us, uint32_t u32ShiftMask) 617 | { 618 | boost::shared_lock oLock; 619 | 620 | //Note the vector contains the base type callback handler pointer so cast to the derived version is this class 621 | //to call function added in the derived version of the callback handler interface class 622 | 623 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers.size(); ui++) 624 | { 625 | cCallbackInterface *pHandler = dynamic_cast(m_vpCallbackHandlers[ui]); 626 | pHandler->coarseFFTShiftMask_callback(i64Timestamp_us, u32ShiftMask); 627 | } 628 | 629 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers_shared.size(); ui++) 630 | { 631 | boost::shared_ptr pHandler = boost::dynamic_pointer_cast(m_vpCallbackHandlers_shared[ui]); 632 | pHandler->coarseFFTShiftMask_callback(i64Timestamp_us, u32ShiftMask); 633 | } 634 | } 635 | 636 | void cRoachAcquisitionServerKATCPClient::sendAttenuationADCChan0(int64_t i64Timestamp_us, double dADCAttenuationChan0_dB) 637 | { 638 | boost::shared_lock oLock; 639 | 640 | //Note the vector contains the base type callback handler pointer so cast to the derived version is this class 641 | //to call function added in the derived version of the callback handler interface class 642 | 643 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers.size(); ui++) 644 | { 645 | cCallbackInterface *pHandler = dynamic_cast(m_vpCallbackHandlers[ui]); 646 | pHandler->attenuationADCChan0_callback(i64Timestamp_us, dADCAttenuationChan0_dB); 647 | } 648 | 649 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers_shared.size(); ui++) 650 | { 651 | boost::shared_ptr pHandler = boost::dynamic_pointer_cast(m_vpCallbackHandlers_shared[ui]); 652 | pHandler->attenuationADCChan0_callback(i64Timestamp_us, dADCAttenuationChan0_dB); 653 | } 654 | } 655 | 656 | void cRoachAcquisitionServerKATCPClient::sendAttenuationADCChan1(int64_t i64Timestamp_us, double dADCAttenuationChan1_dB) 657 | { 658 | boost::shared_lock oLock; 659 | 660 | //Note the vector contains the base type callback handler pointer so cast to the derived version is this class 661 | //to call function added in the derived version of the callback handler interface class 662 | 663 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers.size(); ui++) 664 | { 665 | cCallbackInterface *pHandler = dynamic_cast(m_vpCallbackHandlers[ui]); 666 | pHandler->attenuationADCChan1_callback(i64Timestamp_us, dADCAttenuationChan1_dB); 667 | } 668 | 669 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers_shared.size(); ui++) 670 | { 671 | boost::shared_ptr pHandler = boost::dynamic_pointer_cast(m_vpCallbackHandlers_shared[ui]); 672 | pHandler->attenuationADCChan1_callback(i64Timestamp_us, dADCAttenuationChan1_dB); 673 | } 674 | } 675 | 676 | void cRoachAcquisitionServerKATCPClient::sendNoiseDiodeEnabled(int64_t i64Timestamp_us, bool bNoideDiodeEnabled) 677 | { 678 | boost::shared_lock oLock; 679 | 680 | //Note the vector contains the base type callback handler pointer so cast to the derived version is this class 681 | //to call function added in the derived version of the callback handler interface class 682 | 683 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers.size(); ui++) 684 | { 685 | cCallbackInterface *pHandler = dynamic_cast(m_vpCallbackHandlers[ui]); 686 | pHandler->noiseDiodeEnabled_callback(i64Timestamp_us, bNoideDiodeEnabled); 687 | } 688 | 689 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers_shared.size(); ui++) 690 | { 691 | boost::shared_ptr pHandler = boost::dynamic_pointer_cast(m_vpCallbackHandlers_shared[ui]); 692 | pHandler->noiseDiodeEnabled_callback(i64Timestamp_us, bNoideDiodeEnabled); 693 | } 694 | } 695 | 696 | void cRoachAcquisitionServerKATCPClient::sendNoiseDiodeDutyCycleEnabled(int64_t i64Timestamp_us, bool bNoiseDiodeDutyCyleEnabled) 697 | { 698 | boost::shared_lock oLock; 699 | 700 | //Note the vector contains the base type callback handler pointer so cast to the derived version is this class 701 | //to call function added in the derived version of the callback handler interface class 702 | 703 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers.size(); ui++) 704 | { 705 | cCallbackInterface *pHandler = dynamic_cast(m_vpCallbackHandlers[ui]); 706 | pHandler->noiseDiodeDutyCycleEnabled_callback(i64Timestamp_us, bNoiseDiodeDutyCyleEnabled); 707 | } 708 | 709 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers_shared.size(); ui++) 710 | { 711 | boost::shared_ptr pHandler = boost::dynamic_pointer_cast(m_vpCallbackHandlers_shared[ui]); 712 | pHandler->noiseDiodeDutyCycleEnabled_callback(i64Timestamp_us, bNoiseDiodeDutyCyleEnabled); 713 | } 714 | } 715 | 716 | void cRoachAcquisitionServerKATCPClient::sendNoiseDiodeDutyCycleOnDuration(int64_t i64Timestamp_us, uint32_t u32NAccums) 717 | { 718 | boost::shared_lock oLock; 719 | 720 | //Note the vector contains the base type callback handler pointer so cast to the derived version is this class 721 | //to call function added in the derived version of the callback handler interface class 722 | 723 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers.size(); ui++) 724 | { 725 | cCallbackInterface *pHandler = dynamic_cast(m_vpCallbackHandlers[ui]); 726 | pHandler->noiseDiodeDutyCycleOnDuration_callback(i64Timestamp_us, u32NAccums); 727 | } 728 | 729 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers_shared.size(); ui++) 730 | { 731 | boost::shared_ptr pHandler = boost::dynamic_pointer_cast(m_vpCallbackHandlers_shared[ui]); 732 | pHandler->noiseDiodeDutyCycleOnDuration_callback(i64Timestamp_us, u32NAccums); 733 | } 734 | } 735 | 736 | void cRoachAcquisitionServerKATCPClient::sendNoiseDiodeDutyCycleOffDuration(int64_t i64Timestamp_us, uint32_t u32NAccums) 737 | { 738 | boost::shared_lock oLock; 739 | 740 | //Note the vector contains the base type callback handler pointer so cast to the derived version is this class 741 | //to call function added in the derived version of the callback handler interface class 742 | 743 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers.size(); ui++) 744 | { 745 | cCallbackInterface *pHandler = dynamic_cast(m_vpCallbackHandlers[ui]); 746 | pHandler->noiseDiodeDutyCycleOffDuration_callback(i64Timestamp_us, u32NAccums); 747 | } 748 | 749 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers_shared.size(); ui++) 750 | { 751 | boost::shared_ptr pHandler = boost::dynamic_pointer_cast(m_vpCallbackHandlers_shared[ui]); 752 | pHandler->noiseDiodeDutyCycleOffDuration_callback(i64Timestamp_us, u32NAccums); 753 | } 754 | } 755 | 756 | void cRoachAcquisitionServerKATCPClient::sendOverflowsRegs(int64_t i64Timestamp_us, uint32_t u32OverflowRegs) 757 | { 758 | boost::shared_lock oLock; 759 | 760 | //Note the vector contains the base type callback handler pointer so cast to the derived version is this class 761 | //to call function added in the derived version of the callback handler interface class 762 | 763 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers.size(); ui++) 764 | { 765 | cCallbackInterface *pHandler = dynamic_cast(m_vpCallbackHandlers[ui]); 766 | pHandler->overflowsRegs_callback(i64Timestamp_us, u32OverflowRegs); 767 | } 768 | 769 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers_shared.size(); ui++) 770 | { 771 | boost::shared_ptr pHandler = boost::dynamic_pointer_cast(m_vpCallbackHandlers_shared[ui]); 772 | pHandler->overflowsRegs_callback(i64Timestamp_us, u32OverflowRegs); 773 | } 774 | } 775 | 776 | void cRoachAcquisitionServerKATCPClient::sendEth10GbEUp(int64_t i64Timestamp_us, bool bEth10GbEUp) 777 | { 778 | boost::shared_lock oLock; 779 | 780 | //Note the vector contains the base type callback handler pointer so cast to the derived version is this class 781 | //to call function added in the derived version of the callback handler interface class 782 | 783 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers.size(); ui++) 784 | { 785 | cCallbackInterface *pHandler = dynamic_cast(m_vpCallbackHandlers[ui]); 786 | pHandler->eth10GbEUp_callback(i64Timestamp_us, bEth10GbEUp); 787 | } 788 | 789 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers_shared.size(); ui++) 790 | { 791 | boost::shared_ptr pHandler = boost::dynamic_pointer_cast(m_vpCallbackHandlers_shared[ui]); 792 | pHandler->eth10GbEUp_callback(i64Timestamp_us, bEth10GbEUp); 793 | } 794 | } 795 | 796 | void cRoachAcquisitionServerKATCPClient::sendPPSCount(int64_t i64Timestamp_us, uint32_t u32PPSCount) 797 | { 798 | boost::shared_lock oLock; 799 | 800 | //Note the vector contains the base type callback handler pointer so cast to the derived version is this class 801 | //to call function added in the derived version of the callback handler interface class 802 | 803 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers.size(); ui++) 804 | { 805 | cCallbackInterface *pHandler = dynamic_cast(m_vpCallbackHandlers[ui]); 806 | pHandler->ppsCount_callback(i64Timestamp_us, u32PPSCount); 807 | } 808 | 809 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers_shared.size(); ui++) 810 | { 811 | boost::shared_ptr pHandler = boost::dynamic_pointer_cast(m_vpCallbackHandlers_shared[ui]); 812 | pHandler->ppsCount_callback(i64Timestamp_us, u32PPSCount); 813 | } 814 | } 815 | 816 | void cRoachAcquisitionServerKATCPClient::sendClockFrequency(int64_t i64Timestamp_us, uint32_t u32ClockFrequency_Hz) 817 | { 818 | boost::shared_lock oLock; 819 | 820 | //Note the vector contains the base type callback handler pointer so cast to the derived version is this class 821 | //to call function added in the derived version of the callback handler interface class 822 | 823 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers.size(); ui++) 824 | { 825 | cCallbackInterface *pHandler = dynamic_cast(m_vpCallbackHandlers[ui]); 826 | pHandler->clockFrequency_callback(i64Timestamp_us, u32ClockFrequency_Hz); 827 | } 828 | 829 | for(uint32_t ui = 0; ui < m_vpCallbackHandlers_shared.size(); ui++) 830 | { 831 | boost::shared_ptr pHandler = boost::dynamic_pointer_cast(m_vpCallbackHandlers_shared[ui]); 832 | pHandler->clockFrequency_callback(i64Timestamp_us, u32ClockFrequency_Hz); 833 | } 834 | } 835 | 836 | void cRoachAcquisitionServerKATCPClient::requestStartRecording(const string &strFilenamePrefix, int64_t i64StartTime_us, int64_t i64Duration_us) 837 | { 838 | stringstream oSS; 839 | oSS << string("?startRecording"); 840 | 841 | oSS << string(" "); 842 | if(strFilenamePrefix.length()) 843 | oSS << strFilenamePrefix; 844 | else 845 | oSS << string("\\@"); //Empty string escape sequence for KATCP. Note actually \@ on the telnet line. 846 | 847 | oSS << string(" "); 848 | oSS << i64StartTime_us; 849 | 850 | oSS << string(" "); 851 | oSS << i64Duration_us; 852 | 853 | oSS << string("\n"); 854 | 855 | sendKATCPMessage(oSS.str()); 856 | 857 | cout << "cRoachAcquisitionServerKATCPClient::requestStartRecording() Send start recording request : " << oSS.str().c_str() << endl; 858 | } 859 | 860 | void cRoachAcquisitionServerKATCPClient::requestStopRecording() 861 | { 862 | sendKATCPMessage(string("?stopRecording\n")); 863 | } 864 | 865 | void cRoachAcquisitionServerKATCPClient::requestRecordingStatus() 866 | { 867 | sendKATCPMessage(string("?getRecordingStatus\n")); 868 | } 869 | 870 | void cRoachAcquisitionServerKATCPClient::requestRecordingInfoUpdate() 871 | { 872 | sendKATCPMessage(string("?getRecordingInfo\n")); 873 | } 874 | 875 | void cRoachAcquisitionServerKATCPClient::requestRoachGatewareList() 876 | { 877 | sendKATCPMessage("?getRoachGatewareList\n"); 878 | } 879 | 880 | void cRoachAcquisitionServerKATCPClient::requestRoachProgram(const std::string strScriptPath) 881 | { 882 | stringstream oSS; 883 | oSS << "?programRoach "; 884 | oSS << strScriptPath; 885 | oSS << "\n"; 886 | 887 | sendKATCPMessage(oSS.str()); 888 | } 889 | 890 | void cRoachAcquisitionServerKATCPClient::requestRoachSetStokesEnabled(bool bEnabled) 891 | { 892 | stringstream oSS; 893 | oSS << "?setRoachStokesEnabled "; 894 | if(bEnabled) 895 | { 896 | oSS << "1"; 897 | } 898 | else 899 | { 900 | oSS << "0"; 901 | } 902 | oSS << "\n"; 903 | 904 | sendKATCPMessage(oSS.str()); 905 | } 906 | 907 | void cRoachAcquisitionServerKATCPClient::requestRoachSetAccumulationLength(uint32_t u32Length_nFrames) 908 | { 909 | stringstream oSS; 910 | oSS << "?setRoachAccumulationLength "; 911 | oSS << u32Length_nFrames; 912 | oSS << "\n"; 913 | 914 | sendKATCPMessage(oSS.str()); 915 | } 916 | 917 | void cRoachAcquisitionServerKATCPClient::requestRoachSetCoarseChannelSelect(uint32_t u32ChannelNo) 918 | { 919 | stringstream oSS; 920 | oSS << "?setRoachCoarseChannelSelect "; 921 | oSS << u32ChannelNo; 922 | oSS << "\n"; 923 | 924 | sendKATCPMessage(oSS.str()); 925 | } 926 | 927 | void cRoachAcquisitionServerKATCPClient::requestRoachSetCoarseFFTShiftMask(uint32_t u32FFTShiftMask) 928 | { 929 | stringstream oSS; 930 | oSS << "?setRoachCoarseFFTMask "; 931 | oSS << u32FFTShiftMask; 932 | oSS << "\n"; 933 | 934 | sendKATCPMessage(oSS.str()); 935 | } 936 | 937 | void cRoachAcquisitionServerKATCPClient::requestRoachSetADC0Attenuation(uint32_t u32ADC0Attenuation) 938 | { 939 | stringstream oSS; 940 | oSS << "?setRoachADC0Attenuation "; 941 | oSS << u32ADC0Attenuation; 942 | oSS << "\n"; 943 | 944 | sendKATCPMessage(oSS.str()); 945 | } 946 | 947 | void cRoachAcquisitionServerKATCPClient::requestRoachSetADC1Attenuation(uint32_t u32ADC1Attenuation) 948 | { 949 | stringstream oSS; 950 | oSS << "?setRoachADC1Attenuation "; 951 | oSS << u32ADC1Attenuation; 952 | oSS << "\n"; 953 | 954 | sendKATCPMessage(oSS.str()); 955 | } 956 | 957 | void cRoachAcquisitionServerKATCPClient::requestRoachSetNoiseDiodeEnabled(bool bEnabled) 958 | { 959 | stringstream oSS; 960 | oSS << "?setRoachNoiseDiodeEnabled "; 961 | if(bEnabled) 962 | { 963 | oSS << "1"; 964 | } 965 | else 966 | { 967 | oSS << "0"; 968 | } 969 | oSS << "\n"; 970 | 971 | sendKATCPMessage(oSS.str()); 972 | } 973 | 974 | void cRoachAcquisitionServerKATCPClient::requestRoachSetNoiseDiodeDutyCycleEnabled(bool bEnabled) 975 | { 976 | stringstream oSS; 977 | oSS << "?setRoachNoiseDiodeDutyCycleEnabled "; 978 | if(bEnabled) 979 | { 980 | oSS << "1"; 981 | } 982 | else 983 | { 984 | oSS << "0"; 985 | } 986 | oSS << "\n"; 987 | 988 | sendKATCPMessage(oSS.str()); 989 | } 990 | 991 | void cRoachAcquisitionServerKATCPClient::requestRoachSetNoiseDiodeDutyCycleOnDuration(uint32_t u32NAccums) 992 | { 993 | stringstream oSS; 994 | oSS << "?setRoachNoiseDiodeDutyCycleOnDuration "; 995 | oSS << u32NAccums; 996 | oSS << "\n"; 997 | 998 | sendKATCPMessage(oSS.str()); 999 | } 1000 | 1001 | void cRoachAcquisitionServerKATCPClient::requestRoachSetNoiseDiodeDutyCycleOffDuration(uint32_t u32NAccums) 1002 | { 1003 | stringstream oSS; 1004 | oSS << "?setRoachNoiseDiodeDutyCycleOffDuration "; 1005 | oSS << u32NAccums; 1006 | oSS << "\n"; 1007 | 1008 | sendKATCPMessage(oSS.str()); 1009 | } 1010 | 1011 | void cRoachAcquisitionServerKATCPClient::subscribeToSensors() 1012 | { 1013 | cout << "cRoachAcquisitionServerKATCPClient::subscribeToSensors(): Subscribing to sensors on KATCP server." << endl; 1014 | 1015 | //sendKATCPMessage(string("?sensor-sampling stationControllerConnected period 1000\n")); 1016 | sendKATCPMessage(string("?sensor-sampling actualAntennaAz period 1000\n")); 1017 | sendKATCPMessage(string("?sensor-sampling actualAntennaEl period 1000\n")); 1018 | sendKATCPMessage(string("?sensor-sampling actualSourceOffsetAz period 1000\n")); 1019 | sendKATCPMessage(string("?sensor-sampling actualSourceOffsetEl period 1000\n")); 1020 | sendKATCPMessage(string("?sensor-sampling frequencyRFChan0 period 1000\n")); 1021 | sendKATCPMessage(string("?sensor-sampling frequencyRFChan1 period 1000\n")); 1022 | sendKATCPMessage(string("?sensor-sampling roachConnected auto\n")); 1023 | sendKATCPMessage(string("?sensor-sampling roachStokesEnabled period 1000\n")); 1024 | sendKATCPMessage(string("?sensor-sampling roachAccumulationLength period 1000\n")); 1025 | sendKATCPMessage(string("?sensor-sampling roachCoarseChannelSelect period 1000\n")); 1026 | sendKATCPMessage(string("?sensor-sampling roachFrequencyFs period 1000\n")); 1027 | sendKATCPMessage(string("?sensor-sampling roachSizeOfCoarseFFT period 1000\n")); 1028 | sendKATCPMessage(string("?sensor-sampling roachSizeOfFineFFT period 1000\n")); 1029 | sendKATCPMessage(string("?sensor-sampling roachCoarseFFTShiftMask period 1000\n")); 1030 | sendKATCPMessage(string("?sensor-sampling roachAttenuationADCChan0 period 1000\n")); 1031 | sendKATCPMessage(string("?sensor-sampling roachAttenuationADCChan1 period 1000\n")); 1032 | sendKATCPMessage(string("?sensor-sampling roachNoiseDiodeEnabled period 1000\n")); 1033 | sendKATCPMessage(string("?sensor-sampling roachNoiseDiodeDutyCycleEnabled period 1000\n")); 1034 | sendKATCPMessage(string("?sensor-sampling roachNoiseDiodeDutyCycleOnDuration period 1000\n")); 1035 | sendKATCPMessage(string("?sensor-sampling roachNoiseDiodeDutyCycleOffDuration period 1000\n")); 1036 | sendKATCPMessage(string("?sensor-sampling roachOverflowRegs period 1000\n")); 1037 | sendKATCPMessage(string("?sensor-sampling roachEth10GbEUp period 1000\n")); 1038 | sendKATCPMessage(string("?sensor-sampling roachPPSCount period 1000\n")); 1039 | sendKATCPMessage(string("?sensor-sampling roachClockFrequency period 1000\n")); 1040 | } 1041 | -------------------------------------------------------------------------------- /RoachAcquistionControlWidget.cpp: -------------------------------------------------------------------------------- 1 | //System includes 2 | #include 3 | 4 | //Libary includes 5 | #ifndef Q_MOC_RUN //Qt's MOC and Boost have some issues don't let MOC process boost headers 6 | #include 7 | #include 8 | #endif 9 | 10 | //Local includes 11 | #include "RoachAcquistionControlWidget.h" 12 | #include "ui_RoachAcquistionControlWidget.h" 13 | #include "AVNUtilLibs/Timestamp/Timestamp.h" 14 | #include "AVNDataTypes/SpectrometerDataStream/cSpectrometerOverflowRegisters.h" 15 | 16 | using namespace std; 17 | 18 | cRoachAcquistionControlWidget::cRoachAcquistionControlWidget(cPlotsWidget *pPlotsWidget, QWidget *pParent) : 19 | QDialog(pParent), 20 | m_pUI(new Ui::cRoachAcquistionControlWidget), 21 | m_pPlotsWidget(pPlotsWidget), 22 | m_eTimeSpec(Qt::LocalTime), 23 | m_bIsRecording(false), 24 | m_dFrequencyRFChan0_MHz(0.0), 25 | m_dFrequencyRFChan1_MHz(0.0), 26 | m_bRoachKATCPConnected(false), 27 | m_bStokesEnabled(false), 28 | m_u32AccumulationLength_nFrames(0), 29 | m_dSingleAccumulationLength_ms(0.0), 30 | m_u32CoarseChannelSelect(0), 31 | m_dCoarseChannelSelectBaseband_MHz(0.0), 32 | m_dFrequencyFs_Hz(0.0), 33 | m_u32SizeOfCoarseFFT_nSamp(0), 34 | m_u32SizeOfFineFFT_nSamp(0), 35 | m_u32CoarseFFTShiftMask(0), 36 | m_dAttenuationADCChan0_dB(0.0), 37 | m_dAttenuationADCChan1_dB(0.0), 38 | m_bNoiseDiodeEnabled(false), 39 | m_bNoiseDiodeDutyCycleEnabled(false), 40 | m_u32NoiseDiodeDutyCycleOnDuration_nAccs(0), 41 | m_u32NoiseDiodeDutyCycleOffDuration_nAccs(0), 42 | m_bEth10GbEUp(false), 43 | m_u32PPSCount(0), 44 | m_u32PreviousPPSCount(0), 45 | m_u32ClockFrequency_Hz(0) 46 | { 47 | m_pUI->setupUi(this); 48 | 49 | connectSignalToSlots(); 50 | } 51 | 52 | cRoachAcquistionControlWidget::~cRoachAcquistionControlWidget() 53 | { 54 | if(m_pKATCPClient.get()) 55 | { 56 | m_pKATCPClient->deregisterCallbackHandler(this); 57 | m_pKATCPClient->deregisterCallbackHandler(m_pPlotsWidget); 58 | } 59 | 60 | delete m_pUI; 61 | } 62 | 63 | bool cRoachAcquistionControlWidget::connect(const QString &qstrHostname, uint16_t u16Port) 64 | { 65 | m_pKATCPClient = boost::make_shared(); 66 | 67 | m_pKATCPClient->registerCallbackHandler(this); 68 | m_pKATCPClient->registerCallbackHandler(m_pPlotsWidget); 69 | 70 | if(m_pKATCPClient->connect(qstrHostname.toStdString(), u16Port)) 71 | { 72 | m_oSecondTimer.start(1000); 73 | m_oTwoSecondTimer.start(2000); 74 | m_o200msTimer.start(200); 75 | 76 | return true; 77 | } 78 | else 79 | { 80 | return false; 81 | } 82 | } 83 | 84 | void cRoachAcquistionControlWidget::connectSignalToSlots() 85 | { 86 | //Timers 87 | QObject::connect( &m_oSecondTimer, SIGNAL(timeout()), this, SLOT(slotSecondTimerTrigger()) ); 88 | QObject::connect( &m_oTwoSecondTimer, SIGNAL(timeout()), this, SLOT(slotTwoSecondTimerTrigger()) ); 89 | QObject::connect( &m_o200msTimer, SIGNAL(timeout()), this, SLOT(slot200msTimerTriger()) ); 90 | 91 | //Recording 92 | QObject::connect( m_pUI->pushButton_startStopRecording, SIGNAL(pressed()), this, SLOT(slotStartStopRecordingClicked()) ); 93 | QObject::connect( m_pUI->comboBox_timeZone, SIGNAL(currentIndexChanged(QString)), this, SLOT(slotTimeZoneChanged(QString)) ); 94 | //Select last editted option 95 | QObject::connect( m_pUI->timeEdit_recordAt, SIGNAL(editingFinished()), m_pUI->radioButton_recordAt, SLOT(click()) ); 96 | QObject::connect( m_pUI->doubleSpinBox_recordIn, SIGNAL(editingFinished()), m_pUI->radioButton_recordIn, SLOT(click()) ); 97 | QObject::connect( m_pUI->doubleSpinBox_recordFor, SIGNAL(editingFinished()), m_pUI->radioButton_recordFor, SLOT(click()) ); 98 | 99 | //Roach FPGA / registers 100 | QObject::connect( m_pUI->pushButton_refreshRoachGatewareList, SIGNAL(clicked(bool)), this, SLOT(slotRefreshGatewareList()) ); 101 | QObject::connect( m_pUI->pushButton_gatewareProgram, SIGNAL(clicked()), this, SLOT(slotProgram()) ); 102 | QObject::connect( m_pUI->pushButton_toggleStokesEnabled, SIGNAL(clicked()), this, SLOT(slotToggleStokes()) ); 103 | QObject::connect( m_pUI->pushButton_sendAccumulationLength_frames, SIGNAL(clicked()), this, SLOT(slotSendAccumulationLength_nFrames()) ); 104 | QObject::connect( m_pUI->pushButton_sendAccumulationLength_ms, SIGNAL(clicked()), this, SLOT(slotSendAccumulationLength_ms()) ); 105 | QObject::connect( m_pUI->pushButton_sendCoarseChannelSelect_binNo, SIGNAL(clicked()), this, SLOT(slotSendCoarseChannelSelect_binNo()) ); 106 | QObject::connect( m_pUI->pushButton_sendCoarseChannelSelect_baseband, SIGNAL(clicked()), this, SLOT(slotSendCoarseChannelSelect_baseband()) ); 107 | QObject::connect( m_pUI->pushButton_sendCoarseChannelSelect_finalIF, SIGNAL(clicked()), this, SLOT(slotSendCoarseChannelSelect_finalIF()) ); 108 | QObject::connect( m_pUI->pushButton_sendCoarseChannelSelect_RF0, SIGNAL(clicked()), this, SLOT(slotSendCoarseChannelSelect_RF0()) ); 109 | QObject::connect( m_pUI->pushButton_sendCoarseChannelSelect_RF1, SIGNAL(clicked()), this, SLOT(slotSendCoarseChannelSelect_RF1()) ); 110 | QObject::connect( m_pUI->pushButton_sendCoarseFFTMask, SIGNAL(clicked()), this, SLOT(slotSendCoarseFFTShiftMask()) ); 111 | QObject::connect( m_pUI->pushButton_senADC0Attenuation, SIGNAL(clicked()), this, SLOT(slotSendADC0Attenuation()) ); 112 | QObject::connect( m_pUI->pushButton_sendADC1Attenuation, SIGNAL(clicked()), this, SLOT(slotSendADC1Attenuation()) ); 113 | QObject::connect( m_pUI->pushButton_toggleNoiseDiodeEnabled, SIGNAL(clicked()), this, SLOT(slotToggleNoiseDiodeEnabled()) ); 114 | QObject::connect( m_pUI->pushButton_toggleNoiseDiodeDutyCycleEnabled, SIGNAL(clicked()), this, SLOT(slotToggleNoiseDiodeDutyCycleEnabled()) ); 115 | QObject::connect( m_pUI->pushButton_sendNoiseDiodeDutyCycleOnDuration_accums, SIGNAL(clicked()), this, SLOT(slotSendNoiseDiodeDutyCycleOnDuration_nAccums()) ); 116 | QObject::connect( m_pUI->pushButton_sendNoiseDiodeDutyCycleOnDuration_ms, SIGNAL(clicked()), this, SLOT(slotSendNoiseDiodeDutyCycleOnDuration_ms()) ); 117 | QObject::connect( m_pUI->pushButton_sendNoiseDiodeDutyCycleOffDuration_accums, SIGNAL(clicked()), this, SLOT(slotSendNoiseDiodeDutyCycleOffDuration_nAccums()) ); 118 | QObject::connect( m_pUI->pushButton_sendNoiseDiodeDutyCycleOffDuration_ms, SIGNAL(clicked()), this, SLOT(slotSendNoiseDiodeDutyCycleOffDuration_ms()) ); 119 | 120 | 121 | //Call backs that alter the GUI decoupled by Queued connections to be executed by the GUI thread 122 | qRegisterMetaType("int64_t"); 123 | qRegisterMetaType("uint64_t"); 124 | QObject::connect( this, SIGNAL(sigRecordingInfoUpdate(QString,int64_t,int64_t,int64_t,int64_t,uint64_t, uint64_t)), 125 | this, SLOT(slotRecordingInfoUpdate(QString,int64_t,int64_t,int64_t,int64_t,uint64_t, uint64_t)), Qt::QueuedConnection); 126 | QObject::connect( this, SIGNAL(sigRecordingStarted()), this, SLOT(slotRecordingStarted()), Qt::QueuedConnection); 127 | QObject::connect( this, SIGNAL(sigRecordingStoppped()), this, SLOT(slotRecordingStoppped()), Qt::QueuedConnection); 128 | 129 | QObject::connect( this, SIGNAL(sigUpdateRoachGatewareList()), this, SLOT(slotUpdateRoachGatewareList()), Qt::QueuedConnection); 130 | } 131 | 132 | void cRoachAcquistionControlWidget::slotSecondTimerTrigger() 133 | { 134 | //Update the start time in the GUI every second to the current time. 135 | QDateTime oTimeNow = QDateTime::currentDateTime().addSecs(2); //Now plus 2 seconds 136 | 137 | if(m_eTimeSpec == Qt::UTC) 138 | { 139 | oTimeNow = oTimeNow.toUTC(); 140 | } 141 | 142 | //Update the start time to time now if it is older than time now 143 | //Do change if the user is busy editing the box 144 | if(!m_pUI->timeEdit_recordAt->hasFocus() && m_pUI->timeEdit_recordAt->dateTime() < oTimeNow) 145 | { 146 | m_pUI->timeEdit_recordAt->setDateTime(oTimeNow); 147 | } 148 | 149 | //Update the recording info 150 | QReadLocker oLock(&m_oMutex); 151 | if(m_bIsRecording) 152 | { 153 | m_pKATCPClient->requestRecordingInfoUpdate(); 154 | } 155 | 156 | } 157 | 158 | void cRoachAcquistionControlWidget::slotTwoSecondTimerTrigger() 159 | { 160 | //Check PPS progress: 161 | //Each 2 seconds check that the PPS has progressed by at least 1 162 | 163 | boost::unique_lock oLock(m_oParameterMutex); 164 | 165 | if(m_u32PPSCount - m_u32PreviousPPSCount) 166 | { 167 | m_pUI->label_ppsCount->setStyleSheet("QLabel { background-color : pallete(label)}"); 168 | m_bPPSValid = true; 169 | } 170 | else 171 | { 172 | m_pUI->label_ppsCount->setStyleSheet("QLabel { background-color : red}"); 173 | m_bPPSValid = false; 174 | } 175 | 176 | m_u32PreviousPPSCount = m_u32PPSCount; 177 | } 178 | 179 | void cRoachAcquistionControlWidget::slot200msTimerTriger() 180 | { 181 | //Roach registers are updated in the GUI every 200 ms 182 | slotUpdateRoachGUIParameters(); 183 | } 184 | 185 | void cRoachAcquistionControlWidget::slotStartStopRecordingClicked() 186 | { 187 | if(m_bIsRecording) 188 | { 189 | m_pKATCPClient->requestStopRecording(); 190 | } 191 | else 192 | { 193 | int64_t i64StartTime_us = 0; 194 | int64_t i64Duration_us = 0; 195 | 196 | if(m_pUI->radioButton_recordAt->isChecked()) 197 | { 198 | i64StartTime_us = m_pUI->timeEdit_recordAt->dateTime().toMSecsSinceEpoch() * 1000; 199 | } 200 | else if(m_pUI->radioButton_recordIn->isChecked()) 201 | { 202 | i64StartTime_us = QDateTime::currentMSecsSinceEpoch() * 1000; 203 | 204 | if(m_pUI->comboBox_recordInUnits->currentText() == QString("seconds")) 205 | { 206 | i64StartTime_us += m_pUI->doubleSpinBox_recordIn->value() * 1e6; 207 | } 208 | else if(m_pUI->comboBox_recordInUnits->currentText() == QString("minutes")) 209 | { 210 | i64StartTime_us += m_pUI->doubleSpinBox_recordIn->value() * 60e6; 211 | } 212 | else if(m_pUI->comboBox_recordInUnits->currentText() == QString("hours")) 213 | { 214 | i64StartTime_us += m_pUI->doubleSpinBox_recordIn->value() * 3600e6; 215 | } 216 | } 217 | 218 | 219 | if(m_pUI->radioButton_recordFor->isChecked()) 220 | { 221 | if(m_pUI->comboBox_recordForUnits->currentText() == QString("seconds")) 222 | { 223 | i64Duration_us = m_pUI->doubleSpinBox_recordFor->value() * 1e6; 224 | } 225 | else if(m_pUI->comboBox_recordForUnits->currentText() == QString("minutes")) 226 | { 227 | i64Duration_us = m_pUI->doubleSpinBox_recordFor->value() * 60e6; 228 | } 229 | else if(m_pUI->comboBox_recordForUnits->currentText() == QString("hours")) 230 | { 231 | i64Duration_us = m_pUI->doubleSpinBox_recordFor->value() * 3600e6; 232 | } 233 | } 234 | 235 | m_pKATCPClient->requestStartRecording(m_pUI->lineEdit_filenamePrefix->text().toStdString(), i64StartTime_us, i64Duration_us); 236 | 237 | cout << "cRoachAcquistionControlWidget::slotStartStopRecordingClicked(): Requesting recording start time of " << AVN::stringFromTimestamp_full(i64StartTime_us) << endl; 238 | } 239 | } 240 | 241 | void cRoachAcquistionControlWidget::connected_callback(bool bConnected, const std::string &strHostAddress, uint16_t u16Port, const std::string &strDescription) 242 | { 243 | cout << "cRoachAcquistionControlWidget::connected_callback() Got connected = " << bConnected << " callback" << endl; 244 | } 245 | 246 | void cRoachAcquistionControlWidget::recordingStarted_callback() 247 | { 248 | sigRecordingStarted(); 249 | cout << "cRoachAcquistionControlWidget::recordingStarted_callback() Got recording started callback" << endl; 250 | } 251 | 252 | void cRoachAcquistionControlWidget::recordingStopped_callback() 253 | { 254 | sigRecordingStoppped(); 255 | cout << "cRoachAcquistionControlWidget::recordingStopped_callback() Got recording stopped callback" << endl; 256 | } 257 | 258 | void cRoachAcquistionControlWidget::recordingInfoUpdate_callback(const string &strFilename, int64_t i64StartTime_us, int64_t i64EllapsedTime_us, 259 | int64_t i64StopTime_us, int64_t i64TimeLeft_us, 260 | uint64_t u64CurrentFileSize_B, uint64_t u64DiskSpaceRemaining_B) 261 | { 262 | //Send this info to private slot via queued connection to change GUI. Needs to be a queued connection for execution from the 263 | //main (GUI) thread. You can't alter the GUI from arbitary threads. 264 | 265 | sigRecordingInfoUpdate(QString(strFilename.c_str()), i64StartTime_us, i64EllapsedTime_us, i64StopTime_us, i64TimeLeft_us, u64CurrentFileSize_B, u64DiskSpaceRemaining_B); 266 | } 267 | 268 | void cRoachAcquistionControlWidget::stationControllerKATCPConnected_callback(bool bConnected) 269 | { 270 | boost::unique_lock oLock(m_oParameterMutex); 271 | 272 | m_bStationControllerKATCPConnected = bConnected; 273 | } 274 | 275 | void cRoachAcquistionControlWidget::actualAntennaAz_callback(int64_t i64Timestamp_us, double dAzimuth_deg) 276 | { 277 | //TODO: Add to plotting 278 | } 279 | 280 | void cRoachAcquistionControlWidget::actualAntennaEl_callback(int64_t i64Timestamp_us, double dElevation_deg) 281 | { 282 | //TODO: Add to plotting 283 | } 284 | 285 | void cRoachAcquistionControlWidget::actualSourceOffsetAz_callback(int64_t i64Timestamp_us, double dAzimuthOffset_deg) 286 | { 287 | //TODO: Add to plotting 288 | } 289 | 290 | void cRoachAcquistionControlWidget::actualSourceOffsetEl_callback(int64_t i64Timestamp_us, double dElevationOffset_deg) 291 | { 292 | //TODO: Add to plotting 293 | } 294 | 295 | void cRoachAcquistionControlWidget::frequencyRFChan0_callback(int64_t i64Timestamp_us, double dFrequencyRFChan0_MHz) 296 | { 297 | boost::unique_lock oLock(m_oParameterMutex); 298 | 299 | m_dFrequencyRFChan0_MHz = dFrequencyRFChan0_MHz; 300 | } 301 | 302 | void cRoachAcquistionControlWidget::frequencyRFChan1_callback(int64_t i64Timestamp_us, double dFrequencyRFChan1_MHz) 303 | { 304 | boost::unique_lock oLock(m_oParameterMutex); 305 | 306 | m_dFrequencyRFChan1_MHz = dFrequencyRFChan1_MHz; 307 | } 308 | 309 | void cRoachAcquistionControlWidget::roachGatewareList_callback(const std::vector &vstrGatewareList) 310 | { 311 | { 312 | boost::unique_lock oLock(m_oParameterMutex); 313 | 314 | m_vstrRoachGatewareList = vstrGatewareList; 315 | } 316 | 317 | sigUpdateRoachGatewareList(); 318 | } 319 | 320 | void cRoachAcquistionControlWidget::roachKATCPConnected_callback(bool bConnected) 321 | { 322 | boost::unique_lock oLock(m_oParameterMutex); 323 | 324 | m_bRoachKATCPConnected = bConnected; 325 | } 326 | 327 | void cRoachAcquistionControlWidget::stokesEnabled_callback(bool bEnabled) 328 | { 329 | boost::unique_lock oLock(m_oParameterMutex); 330 | 331 | m_bStokesEnabled = bEnabled; 332 | } 333 | 334 | void cRoachAcquistionControlWidget::accumulationLength_callback(int64_t i64Timestamp_us, uint32_t u32NFrames) 335 | { 336 | boost::unique_lock oLock(m_oParameterMutex); 337 | 338 | m_u32AccumulationLength_nFrames = u32NFrames; 339 | } 340 | 341 | void cRoachAcquistionControlWidget::coarseChannelSelect_callback(int64_t i64Timestamp_us, uint32_t u32ChannelNo) 342 | { 343 | boost::unique_lock oLock(m_oParameterMutex); 344 | 345 | m_u32CoarseChannelSelect = u32ChannelNo; 346 | 347 | m_dCoarseChannelSelectBaseband_MHz = (double)m_u32CoarseChannelSelect / (m_u32SizeOfCoarseFFT_nSamp / 2) * (m_dFrequencyFs_Hz * 1e6 / 2); 348 | } 349 | 350 | void cRoachAcquistionControlWidget::frequencyFs_callback(double dFrequencyFs_Hz) 351 | { 352 | boost::unique_lock oLock(m_oParameterMutex); 353 | 354 | m_dFrequencyFs_Hz = dFrequencyFs_Hz; 355 | 356 | m_dSingleAccumulationLength_ms = 1 / (m_dFrequencyFs_Hz) * m_u32SizeOfCoarseFFT_nSamp; 357 | if(m_u32SizeOfFineFFT_nSamp) 358 | { 359 | m_dSingleAccumulationLength_ms *= m_u32SizeOfFineFFT_nSamp; 360 | } 361 | m_dSingleAccumulationLength_ms *= 1000; 362 | 363 | m_dCoarseChannelSelectBaseband_MHz = (double)m_u32CoarseChannelSelect / (m_u32SizeOfCoarseFFT_nSamp / 2) * (m_dFrequencyFs_Hz * 1e6 / 2); 364 | } 365 | 366 | void cRoachAcquistionControlWidget::sizeOfCoarseFFT_callback(uint32_t u32SizeOfCoarseFFT_nSamp) 367 | { 368 | boost::unique_lock oLock(m_oParameterMutex); 369 | 370 | m_u32SizeOfCoarseFFT_nSamp = u32SizeOfCoarseFFT_nSamp; 371 | 372 | m_dSingleAccumulationLength_ms = 1 / (m_dFrequencyFs_Hz) * m_u32SizeOfCoarseFFT_nSamp; 373 | if(m_u32SizeOfFineFFT_nSamp) 374 | { 375 | m_dSingleAccumulationLength_ms *= m_u32SizeOfFineFFT_nSamp; 376 | } 377 | m_dSingleAccumulationLength_ms *= 1000; 378 | 379 | m_dCoarseChannelSelectBaseband_MHz = (double)m_u32CoarseChannelSelect / (m_u32SizeOfCoarseFFT_nSamp / 2) * (m_dFrequencyFs_Hz * 1e6 / 2); 380 | } 381 | 382 | void cRoachAcquistionControlWidget::sizeOfFineFFT_callback(uint32_t u32SizeOfFineFFT_nSamp) 383 | { 384 | boost::unique_lock oLock(m_oParameterMutex); 385 | 386 | m_u32SizeOfFineFFT_nSamp = u32SizeOfFineFFT_nSamp; 387 | 388 | m_dSingleAccumulationLength_ms = 1 / (m_dFrequencyFs_Hz) * m_u32SizeOfCoarseFFT_nSamp; 389 | if(m_u32SizeOfFineFFT_nSamp) 390 | { 391 | m_dSingleAccumulationLength_ms *= m_u32SizeOfFineFFT_nSamp; 392 | } 393 | m_dSingleAccumulationLength_ms *= 1000; 394 | } 395 | 396 | void cRoachAcquistionControlWidget::coarseFFTShiftMask_callback(int64_t i64Timestamp_us, uint32_t u32ShiftMask) 397 | { 398 | boost::unique_lock oLock(m_oParameterMutex); 399 | 400 | m_u32CoarseFFTShiftMask = u32ShiftMask; 401 | } 402 | 403 | void cRoachAcquistionControlWidget::attenuationADCChan0_callback(int64_t i64Timestamp_us, double dADCAttenuationChan0_dB) 404 | { 405 | boost::unique_lock oLock(m_oParameterMutex); 406 | 407 | m_dAttenuationADCChan0_dB = dADCAttenuationChan0_dB; 408 | } 409 | 410 | void cRoachAcquistionControlWidget::attenuationADCChan1_callback(int64_t i64Timestamp_us, double dADCAttenuationChan1_dB) 411 | { 412 | boost::unique_lock oLock(m_oParameterMutex); 413 | 414 | m_dAttenuationADCChan1_dB = dADCAttenuationChan1_dB; 415 | } 416 | void cRoachAcquistionControlWidget::noiseDiodeEnabled_callback(int64_t i64Timestamp_us, bool bNoiseDiodeEnabled) 417 | { 418 | boost::unique_lock oLock(m_oParameterMutex); 419 | 420 | m_bNoiseDiodeEnabled = bNoiseDiodeEnabled; 421 | } 422 | 423 | void cRoachAcquistionControlWidget::noiseDiodeDutyCycleEnabled_callback(int64_t i64Timestamp_us, bool bNoiseDiodeDutyCyleEnabled) 424 | { 425 | boost::unique_lock oLock(m_oParameterMutex); 426 | 427 | m_bNoiseDiodeDutyCycleEnabled = bNoiseDiodeDutyCyleEnabled; 428 | } 429 | 430 | void cRoachAcquistionControlWidget::noiseDiodeDutyCycleOnDuration_callback(int64_t i64Timestamp_us, uint32_t u32NAccums) 431 | { 432 | boost::unique_lock oLock(m_oParameterMutex); 433 | 434 | m_u32NoiseDiodeDutyCycleOnDuration_nAccs = u32NAccums; 435 | } 436 | 437 | void cRoachAcquistionControlWidget::noiseDiodeDutyCycleOffDuration_callback(int64_t i64Timestamp_us, uint32_t u32NAccums) 438 | { 439 | boost::unique_lock oLock(m_oParameterMutex); 440 | 441 | m_u32NoiseDiodeDutyCycleOffDuration_nAccs = u32NAccums; 442 | } 443 | 444 | void cRoachAcquistionControlWidget::overflowsRegs_callback(int64_t i64Timestamp_us, uint32_t u32OverflowRegs) 445 | { 446 | boost::unique_lock oLock(m_oParameterMutex); 447 | 448 | m_u32OverflowsRegs = u32OverflowRegs; 449 | } 450 | 451 | void cRoachAcquistionControlWidget::eth10GbEUp_callback(int64_t i64Timestamp_us, bool bEth10GbEUp) 452 | { 453 | boost::unique_lock oLock(m_oParameterMutex); 454 | 455 | m_bEth10GbEUp = bEth10GbEUp; 456 | } 457 | 458 | void cRoachAcquistionControlWidget::ppsCount_callback(int64_t i64Timestamp_us, uint32_t u32PPSCount) 459 | { 460 | boost::unique_lock oLock(m_oParameterMutex); 461 | 462 | m_u32PPSCount = u32PPSCount; 463 | } 464 | 465 | void cRoachAcquistionControlWidget::clockFrequency_callback(int64_t i64Timestamp_us, uint32_t u32ClockFrequency_Hz) 466 | { 467 | boost::unique_lock oLock(m_oParameterMutex); 468 | 469 | m_u32ClockFrequency_Hz = u32ClockFrequency_Hz; 470 | } 471 | 472 | void cRoachAcquistionControlWidget::slotUpdateRoachGUIParameters() 473 | { 474 | //This design is not greatly efficient as it calls this function which writes all values for the update of any of them. 475 | //For now it appears good enough. 476 | 477 | //FYI connections to this slot is queued so it is save to lock the same mutex here as in the calling function. 478 | boost::unique_lock oLock(m_oParameterMutex); 479 | 480 | if(m_bRoachKATCPConnected) 481 | { 482 | m_pUI->label_roachConnection->setText(QString("Connected")); 483 | } 484 | else 485 | { 486 | m_pUI->label_roachConnection->setText(QString("Not connected")); 487 | } 488 | 489 | if(m_bStationControllerKATCPConnected) 490 | { 491 | m_pUI->label_stationControllerConnection->setText(QString("Connected")); 492 | } 493 | else 494 | { 495 | m_pUI->label_stationControllerConnection->setText(QString("Not connected")); 496 | } 497 | 498 | if(m_bStokesEnabled) 499 | { 500 | m_pUI->label_stokesEnabled->setText(QString("True")); 501 | } 502 | else 503 | { 504 | m_pUI->label_stokesEnabled->setText(QString("False")); 505 | } 506 | 507 | m_pUI->label_accumulationLength_nFrames->setText(QString("%1 frames").arg(m_u32AccumulationLength_nFrames)); 508 | 509 | m_pUI->label_accumulationLength_ms->setText(QString("%1 ms").arg(m_u32AccumulationLength_nFrames * m_dSingleAccumulationLength_ms)); 510 | 511 | if(m_u32SizeOfFineFFT_nSamp) 512 | { 513 | m_pUI->label_coarseChannelSelect_binNo->setText(QString("%1").arg(m_u32CoarseChannelSelect)); 514 | 515 | m_pUI->label_coarseChannelSelect_baseband->setText(QString("%1 MHz").arg(m_dCoarseChannelSelectBaseband_MHz)); 516 | 517 | m_pUI->label_coarseChannelSelect_finalIF->setText(QString("%1 MHz").arg(m_dFrequencyFs_Hz - m_dCoarseChannelSelectBaseband_MHz)); //Assume 2nd Nyquist zone 518 | 519 | //TODO: Not sure if this is right way around relative to RF. 520 | //Presumably, the first mixing stage is low side injection so no spectral flipping. 521 | //The second mixing stage is high side which causes a flip. 522 | //The sampling is second Nqyuist zone which also causes a flip and so the spectrum 523 | //The correct way around. Hence simply add the coarse channel frequnecy offset. 524 | if(m_dFrequencyRFChan0_MHz) 525 | { 526 | m_pUI->label_coarseChannelSelect_RF0->setText(QString("%1").arg(m_dFrequencyRFChan0_MHz - (m_dFrequencyFs_Hz / 4) + m_dCoarseChannelSelectBaseband_MHz)); 527 | } 528 | else 529 | { 530 | m_pUI->label_coarseChannelSelect_RF0->setText(QString("RF frequency unavailable.")); 531 | } 532 | 533 | if(m_dFrequencyRFChan1_MHz) 534 | { 535 | m_pUI->label_coarseChannelSelect_RF1->setText(QString("%1").arg(m_dFrequencyRFChan1_MHz - (m_dFrequencyFs_Hz / 4) + m_dCoarseChannelSelectBaseband_MHz)); 536 | } 537 | else 538 | { 539 | m_pUI->label_coarseChannelSelect_RF1->setText(QString("RF frequency unavailable.")); 540 | } 541 | 542 | m_pUI->spinBox_coarseChannelSelect_binNo->setEnabled(true); 543 | m_pUI->doubleSpinBox_coarseChannelFrequencyBaseband_MHz->setEnabled(true); 544 | m_pUI->doubleSpinBox_coarseChannelFrequencyIF_MHz->setEnabled(true); 545 | m_pUI->doubleSpinBox_coarseChannelFrequencyRF0_MHz->setEnabled(true); 546 | m_pUI->doubleSpinBox_coarseChannelFrequencyRF1_MHz->setEnabled(true); 547 | 548 | m_pUI->pushButton_sendCoarseChannelSelect_binNo->setEnabled(true); 549 | m_pUI->pushButton_sendCoarseChannelSelect_baseband->setEnabled(true); 550 | m_pUI->pushButton_sendCoarseChannelSelect_finalIF->setEnabled(true); 551 | m_pUI->pushButton_sendCoarseChannelSelect_RF0->setEnabled(true); 552 | m_pUI->pushButton_sendCoarseChannelSelect_RF1->setEnabled(true); 553 | } 554 | else 555 | { 556 | m_pUI->label_coarseChannelSelect_binNo->setText(QString("N/A")); 557 | m_pUI->label_coarseChannelSelect_baseband->setText(QString("N/A")); 558 | m_pUI->label_coarseChannelSelect_finalIF->setText(QString("N/A")); 559 | m_pUI->label_coarseChannelSelect_RF0->setText(QString("N/A")); 560 | m_pUI->label_coarseChannelSelect_RF1->setText(QString("N/A")); 561 | 562 | m_pUI->spinBox_coarseChannelSelect_binNo->setEnabled(false); 563 | m_pUI->doubleSpinBox_coarseChannelFrequencyBaseband_MHz->setEnabled(false); 564 | m_pUI->doubleSpinBox_coarseChannelFrequencyIF_MHz->setEnabled(false); 565 | m_pUI->doubleSpinBox_coarseChannelFrequencyRF0_MHz->setEnabled(false); 566 | m_pUI->doubleSpinBox_coarseChannelFrequencyRF1_MHz->setEnabled(false); 567 | 568 | m_pUI->pushButton_sendCoarseChannelSelect_binNo->setEnabled(false); 569 | m_pUI->pushButton_sendCoarseChannelSelect_baseband->setEnabled(false); 570 | m_pUI->pushButton_sendCoarseChannelSelect_finalIF->setEnabled(false); 571 | m_pUI->pushButton_sendCoarseChannelSelect_RF0->setEnabled(false); 572 | m_pUI->pushButton_sendCoarseChannelSelect_RF1->setEnabled(false); 573 | } 574 | 575 | m_pUI->label_coarseFFTShiftMask->setText(QString("%1").arg(m_u32CoarseFFTShiftMask)); 576 | 577 | m_pUI->label_ADC0Attenuation->setText(QString("%1 dB").arg(m_dAttenuationADCChan0_dB)); 578 | 579 | m_pUI->label_ADC1Attenuation->setText(QString("%1 dB").arg(m_dAttenuationADCChan1_dB)); 580 | 581 | if(m_bNoiseDiodeEnabled) 582 | { 583 | m_pUI->label_noideDiodeEnabled->setText(QString("True")); 584 | } 585 | else 586 | { 587 | m_pUI->label_noideDiodeEnabled->setText(QString("False")); 588 | } 589 | 590 | m_pUI->spinBox_noiseDiodeDutyCycleOnDuration_ms->setEnabled(m_bNoiseDiodeEnabled && m_bNoiseDiodeDutyCycleEnabled); 591 | m_pUI->spinBox_noiseDiodeDutyCycleOffDuration_accums->setEnabled(m_bNoiseDiodeEnabled && m_bNoiseDiodeDutyCycleEnabled); 592 | m_pUI->spinBox_noiseDiodeDutyCycleOffDuration_ms->setEnabled(m_bNoiseDiodeEnabled && m_bNoiseDiodeDutyCycleEnabled); 593 | 594 | m_pUI->pushButton_toggleNoiseDiodeDutyCycleEnabled->setEnabled(m_bNoiseDiodeEnabled); 595 | m_pUI->pushButton_sendNoiseDiodeDutyCycleOnDuration_accums->setEnabled(m_bNoiseDiodeEnabled && m_bNoiseDiodeDutyCycleEnabled); 596 | m_pUI->pushButton_sendNoiseDiodeDutyCycleOnDuration_ms->setEnabled(m_bNoiseDiodeEnabled && m_bNoiseDiodeDutyCycleEnabled); 597 | m_pUI->pushButton_sendNoiseDiodeDutyCycleOffDuration_accums->setEnabled(m_bNoiseDiodeEnabled && m_bNoiseDiodeDutyCycleEnabled); 598 | m_pUI->pushButton_sendNoiseDiodeDutyCycleOffDuration_ms->setEnabled(m_bNoiseDiodeEnabled && m_bNoiseDiodeDutyCycleEnabled); 599 | 600 | if(m_bNoiseDiodeDutyCycleEnabled) 601 | { 602 | m_pUI->label_noiseDiodeDutyCycleEnabled->setText(QString("True")); 603 | } 604 | else 605 | { 606 | m_pUI->label_noiseDiodeDutyCycleEnabled->setText(QString("False")); 607 | } 608 | 609 | m_pUI->label_noiseDiodeDutyCycleOnDuration_accums->setText(QString("%1").arg(m_u32NoiseDiodeDutyCycleOnDuration_nAccs)); 610 | 611 | m_pUI->label_noiseDiodeDutyCycleOnDuration_ms->setText(QString("%1 ms").arg(m_u32NoiseDiodeDutyCycleOnDuration_nAccs * m_dSingleAccumulationLength_ms * m_u32AccumulationLength_nFrames)); 612 | 613 | m_pUI->label_noiseDiodeDutyCycleOffDuration_accums->setText(QString("%1").arg(m_u32NoiseDiodeDutyCycleOffDuration_nAccs)); 614 | 615 | m_pUI->label_noiseDiodeDutyCycleOffDuration_ms->setText(QString("%1 ms").arg(m_u32NoiseDiodeDutyCycleOffDuration_nAccs * m_dSingleAccumulationLength_ms * m_u32AccumulationLength_nFrames)); 616 | 617 | cSpectrometerOverflowRegisters oOverflowRegisters(m_u32OverflowsRegs); 618 | 619 | if(oOverflowRegisters.m_bADC0OverRange) 620 | { 621 | m_pUI->label_adc0OverRange->setText(QString("True")); 622 | } 623 | else 624 | { 625 | m_pUI->label_adc0OverRange->setText(QString("False")); 626 | } 627 | 628 | if(oOverflowRegisters.m_bADC1OverRange) 629 | { 630 | m_pUI->label_adc1OverRange->setText("True"); 631 | } 632 | else 633 | { 634 | m_pUI->label_adc1OverRange->setText("False"); 635 | } 636 | 637 | if(oOverflowRegisters.m_bCoarseFFT0Overflow) 638 | { 639 | m_pUI->label_coarseFFT0OverRange->setText("True"); 640 | } 641 | else 642 | { 643 | m_pUI->label_coarseFFT0OverRange->setText("False"); 644 | } 645 | 646 | if(oOverflowRegisters.m_bCoarseFFT1Overflow) 647 | { 648 | m_pUI->label_coarseFFT1OverRange->setText("True"); 649 | } 650 | else 651 | { 652 | m_pUI->label_coarseFFT1OverRange->setText("False"); 653 | } 654 | 655 | if(oOverflowRegisters.m_bPacketiserOverflow) 656 | { 657 | m_pUI->label_packetiserOverflow->setText("True"); 658 | } 659 | else 660 | { 661 | m_pUI->label_packetiserOverflow->setText("False"); 662 | } 663 | 664 | if(oOverflowRegisters.m_bQueueFull) 665 | { 666 | m_pUI->label_queueFull->setText("True"); 667 | } 668 | else 669 | { 670 | m_pUI->label_queueFull->setText("False"); 671 | } 672 | 673 | if(oOverflowRegisters.m_bQueueFull) 674 | { 675 | m_pUI->label_queueFull->setText("True"); 676 | } 677 | else 678 | { 679 | m_pUI->label_queueFull->setText("False"); 680 | } 681 | 682 | if(oOverflowRegisters.m_b10GbETxOverflow) 683 | { 684 | m_pUI->label_10GbETxOverflow->setText("True"); 685 | } 686 | else 687 | { 688 | m_pUI->label_10GbETxOverflow->setText("False"); 689 | } 690 | 691 | if(m_bEth10GbEUp) 692 | { 693 | m_pUI->label_10GbELinkUp->setText(QString("True")); 694 | } 695 | else 696 | { 697 | m_pUI->label_10GbELinkUp->setText(QString("False")); 698 | } 699 | 700 | m_pUI->label_ppsCount->setText(QString("%1").arg(m_u32PPSCount)); 701 | 702 | m_pUI->label_fpgaClock->setText(QString("%1 Hz").arg(m_u32ClockFrequency_Hz)); 703 | 704 | //Flag an parameters which are not valid 705 | checkParametersValid(); 706 | } 707 | 708 | void cRoachAcquistionControlWidget::slotUpdateRoachGatewareList() 709 | { 710 | boost::unique_lock oLock(m_oParameterMutex); 711 | 712 | QString qstrCurrent = m_pUI->comboBox_gatewareSelect->currentText(); 713 | 714 | m_pUI->comboBox_gatewareSelect->clear(); 715 | 716 | uint32_t u32Index = 0; 717 | for(uint32_t ui = 0; ui < m_vstrRoachGatewareList.size(); ui++) 718 | { 719 | m_pUI->comboBox_gatewareSelect->addItem(QString(m_vstrRoachGatewareList[ui].c_str())); 720 | 721 | //Try to find the previous selection to reselect and current. 722 | if(!m_vstrRoachGatewareList[ui].compare(qstrCurrent.toStdString())) 723 | u32Index = ui; 724 | } 725 | 726 | m_pUI->comboBox_gatewareSelect->setCurrentIndex(u32Index); 727 | } 728 | 729 | void cRoachAcquistionControlWidget::checkParametersValid() 730 | { 731 | //Change the background of any label representing a value which is out of range to red. 732 | //The the range is hardcode here for the most part. It migth be better to move towards a more 733 | //programmatic solution in future based on KATCP's sensor's valid-range. 734 | 735 | cSpectrometerOverflowRegisters oOverflowRegisters(m_u32OverflowsRegs); 736 | 737 | if(m_bRoachKATCPConnected) 738 | { 739 | m_pUI->label_roachConnection->setStyleSheet("QLabel { background-color : pallete(label)}"); 740 | } 741 | else 742 | { 743 | m_pUI->label_roachConnection->setStyleSheet("QLabel { background-color : red}"); 744 | } 745 | 746 | if(m_bStationControllerKATCPConnected) 747 | { 748 | m_pUI->label_stationControllerConnection->setStyleSheet("QLabel { background-color : pallete(label)}"); 749 | } 750 | else 751 | { 752 | m_pUI->label_stationControllerConnection->setStyleSheet("QLabel { background-color : red}"); 753 | } 754 | 755 | if(!oOverflowRegisters.m_bADC0OverRange) 756 | { 757 | m_pUI->label_adc0OverRange->setStyleSheet("QLabel { background-color : pallete(label)}"); 758 | } 759 | else 760 | { 761 | m_pUI->label_adc0OverRange->setStyleSheet("QLabel { background-color : red}"); 762 | } 763 | 764 | if(!oOverflowRegisters.m_bADC1OverRange) 765 | { 766 | m_pUI->label_adc1OverRange->setStyleSheet("QLabel { background-color : pallete(label)}"); 767 | } 768 | else 769 | { 770 | m_pUI->label_adc1OverRange->setStyleSheet("QLabel { background-color : red}"); 771 | } 772 | 773 | if(!oOverflowRegisters.m_bCoarseFFT0Overflow) 774 | { 775 | m_pUI->label_coarseFFT0OverRange->setStyleSheet("QLabel { background-color : pallete(label)}"); 776 | } 777 | else 778 | { 779 | m_pUI->label_coarseFFT0OverRange->setStyleSheet("QLabel { background-color : red}"); 780 | } 781 | 782 | if(!oOverflowRegisters.m_bCoarseFFT1Overflow) 783 | { 784 | m_pUI->label_coarseFFT1OverRange->setStyleSheet("QLabel { background-color : pallete(label)}"); 785 | } 786 | else 787 | { 788 | m_pUI->label_coarseFFT1OverRange->setStyleSheet("QLabel { background-color : red}"); 789 | } 790 | 791 | if(!oOverflowRegisters.m_bPacketiserOverflow) 792 | { 793 | m_pUI->label_packetiserOverflow->setStyleSheet("QLabel { background-color : pallete(label)}"); 794 | } 795 | else 796 | { 797 | m_pUI->label_packetiserOverflow->setStyleSheet("QLabel { background-color : red}"); 798 | } 799 | 800 | if(!oOverflowRegisters.m_bQueueFull) 801 | { 802 | m_pUI->label_queueFull->setStyleSheet("QLabel { background-color : pallete(label)}"); 803 | } 804 | else 805 | { 806 | m_pUI->label_queueFull->setStyleSheet("QLabel { background-color : red}"); 807 | } 808 | 809 | if(!oOverflowRegisters.m_b10GbETxOverflow) 810 | { 811 | m_pUI->label_10GbETxOverflow->setStyleSheet("QLabel { background-color : pallete(label)}"); 812 | } 813 | else 814 | { 815 | m_pUI->label_10GbETxOverflow->setStyleSheet("QLabel { background-color : red}"); 816 | } 817 | 818 | if(m_bEth10GbEUp) 819 | { 820 | m_pUI->label_10GbELinkUp->setStyleSheet("QLabel { background-color : pallete(label)}"); 821 | } 822 | else 823 | { 824 | m_pUI->label_10GbELinkUp->setStyleSheet("QLabel { background-color : red}"); 825 | } 826 | 827 | if(m_u32ClockFrequency_Hz == 200000000) 828 | { 829 | m_pUI->label_fpgaClock->setStyleSheet("QLabel { background-color : pallete(label)}"); 830 | } 831 | else 832 | { 833 | m_pUI->label_fpgaClock->setStyleSheet("QLabel { background-color : red}"); 834 | } 835 | 836 | //Check all variables and flag "Registers" label in GUI with red background if any fail 837 | bool bGlobalError = oOverflowRegisters.m_bADC0OverRange 838 | || oOverflowRegisters.m_bADC1OverRange 839 | || oOverflowRegisters.m_bCoarseFFT0Overflow 840 | || oOverflowRegisters.m_bCoarseFFT1Overflow 841 | || oOverflowRegisters.m_bPacketiserOverflow 842 | || oOverflowRegisters.m_bQueueFull 843 | || oOverflowRegisters.m_b10GbETxOverflow 844 | || !m_bEth10GbEUp 845 | || m_u32ClockFrequency_Hz != 200000000 846 | || !m_bPPSValid; 847 | 848 | if(bGlobalError) 849 | { 850 | m_pUI->label_registers->setStyleSheet("QLabel { background-color : red}"); 851 | } 852 | else 853 | { 854 | m_pUI->label_registers->setStyleSheet("QLabel { background-color : pallete(label)}"); 855 | } 856 | 857 | } 858 | 859 | 860 | void cRoachAcquistionControlWidget::slotRecordingInfoUpdate(const QString &qstrFilename, int64_t i64StartTime_us, int64_t i64EllapsedTime_us, 861 | int64_t i64StopTime_us, int64_t i64TimeLeft_us, 862 | uint64_t u64CurrentFileSize_B, uint64_t u64DiskSpaceRemaining_B) 863 | { 864 | //Update info about the recording progress in the GUI 865 | 866 | if(i64EllapsedTime_us < 0) 867 | { 868 | m_pUI->label_status->setText(QString("Recording queued: Starting in %1").arg(AVN::stringFromTimeDuration(-i64EllapsedTime_us).c_str())); 869 | setWindowTitle(QString("Roach Aquisition Control - Recording queued...")); 870 | 871 | m_pUI->label_recordingStartTime->setText(QString("")); 872 | m_pUI->label_recordingDuration->setText(QString("")); 873 | m_pUI->label_recordingStopTime->setText(QString("")); 874 | m_pUI->label_recordingTimeLeft->setText(QString("")); 875 | m_pUI->label_currentFileSize->setText(QString("")); 876 | } 877 | else 878 | { 879 | m_pUI->label_status->setText(QString("Recording: %1").arg(qstrFilename)); 880 | setWindowTitle(QString("Roach Aquisition Control - Recording")); 881 | 882 | m_pUI->label_recordingStartTime->setText(QString(AVN::stringFromTimestamp_full(i64StartTime_us).c_str())); 883 | m_pUI->label_recordingDuration->setText(QString(AVN::stringFromTimeDuration(i64EllapsedTime_us).c_str())); 884 | if(i64StopTime_us == LLONG_MAX) 885 | { 886 | m_pUI->label_recordingStopTime->setText(QString("User controlled.")); 887 | m_pUI->label_recordingTimeLeft->setText(QString("N/A")); 888 | } 889 | else 890 | { 891 | m_pUI->label_recordingStopTime->setText(QString(AVN::stringFromTimestamp_full(i64StopTime_us).c_str())); 892 | m_pUI->label_recordingTimeLeft->setText(QString(AVN::stringFromTimeDuration(i64TimeLeft_us).c_str())); 893 | } 894 | 895 | m_pUI->label_currentFileSize->setText(QString("%1 MB").arg((double)u64CurrentFileSize_B / 1e6, 0, 'f', 3)); 896 | } 897 | 898 | //Always update disk space 899 | m_pUI->label_diskSpaceRemaining->setText(QString("%1 GB").arg((double)u64DiskSpaceRemaining_B / 1e9, 0, 'f', 3)); 900 | } 901 | 902 | void cRoachAcquistionControlWidget::slotRecordingStarted() 903 | { 904 | { 905 | QWriteLocker oLock(&m_oMutex); 906 | m_bIsRecording = true; 907 | } 908 | 909 | m_pUI->pushButton_startStopRecording->setText(QString("Stop recording")); 910 | } 911 | 912 | void cRoachAcquistionControlWidget::slotRecordingStoppped() 913 | { 914 | { 915 | QWriteLocker oLock(&m_oMutex); 916 | m_bIsRecording = false; 917 | } 918 | 919 | m_pUI->pushButton_startStopRecording->setText(QString("Start recording")); 920 | 921 | m_pUI->label_status->setText(QString("Not recording.")); 922 | setWindowTitle(QString("Roach Aquisition Control")); 923 | 924 | m_pUI->label_recordingStartTime->setText(QString("")); 925 | m_pUI->label_recordingDuration->setText(QString("")); 926 | m_pUI->label_recordingStopTime->setText(QString("")); 927 | m_pUI->label_recordingTimeLeft->setText(QString("")); 928 | } 929 | 930 | void cRoachAcquistionControlWidget::slotTimeZoneChanged(QString qstrTimeZone) 931 | { 932 | if(qstrTimeZone == QString("UTC")) 933 | { 934 | m_eTimeSpec = Qt::UTC; 935 | cout << "Set start time display to UTC" << endl; 936 | } 937 | 938 | if(qstrTimeZone == QString("Local")) 939 | { 940 | m_eTimeSpec = Qt::LocalTime; 941 | cout << "Set start time display to local time" << endl; 942 | } 943 | 944 | m_pUI->timeEdit_recordAt->setTimeSpec(m_eTimeSpec); 945 | } 946 | 947 | void cRoachAcquistionControlWidget::closeEvent(QCloseEvent *pEvent) 948 | { 949 | //Intercept close event and hide the dialogue instead 950 | pEvent->ignore(); 951 | this->hide(); 952 | } 953 | 954 | void cRoachAcquistionControlWidget::slotRefreshGatewareList() 955 | { 956 | m_pKATCPClient->requestRoachGatewareList(); 957 | } 958 | 959 | void cRoachAcquistionControlWidget::slotProgram() 960 | { 961 | m_pKATCPClient->requestRoachProgram(m_pUI->comboBox_gatewareSelect->currentText().toStdString()); 962 | } 963 | 964 | void cRoachAcquistionControlWidget::slotToggleStokes() 965 | { 966 | boost::unique_lock oLock(m_oParameterMutex); 967 | m_pKATCPClient->requestRoachSetStokesEnabled(!m_bStokesEnabled); 968 | } 969 | 970 | void cRoachAcquistionControlWidget::slotSendAccumulationLength_nFrames() 971 | { 972 | m_pKATCPClient->requestRoachSetAccumulationLength(m_pUI->spinBox_accumulationLength_nFrames->value()); 973 | } 974 | 975 | void cRoachAcquistionControlWidget::slotSendAccumulationLength_ms() 976 | { 977 | //Calculation number of accumulations in FFT frames (round up) 978 | uint32_t u32NFrames; 979 | { 980 | boost::unique_lock oLock(m_oParameterMutex); 981 | u32NFrames = boost::math::lround(m_pUI->doubleSpinBox_accumulationLength_ms->value() / m_dSingleAccumulationLength_ms + 0.5); 982 | } 983 | 984 | m_pKATCPClient->requestRoachSetAccumulationLength(u32NFrames); 985 | } 986 | 987 | void cRoachAcquistionControlWidget::slotSendCoarseChannelSelect_binNo() 988 | { 989 | m_pKATCPClient->requestRoachSetCoarseChannelSelect(m_pUI->spinBox_coarseChannelSelect_binNo->value()); 990 | } 991 | 992 | void cRoachAcquistionControlWidget::slotSendCoarseChannelSelect_baseband() 993 | { 994 | uint32_t u32CoarseChannelSelect; 995 | { 996 | boost::unique_lock oLock(m_oParameterMutex); 997 | u32CoarseChannelSelect = m_pUI->doubleSpinBox_coarseChannelFrequencyBaseband_MHz->value() * (m_u32SizeOfCoarseFFT_nSamp / 2) / (m_dFrequencyFs_Hz / 2); 998 | } 999 | 1000 | m_pKATCPClient->requestRoachSetCoarseChannelSelect(u32CoarseChannelSelect); 1001 | } 1002 | 1003 | void cRoachAcquistionControlWidget::slotSendCoarseChannelSelect_finalIF() 1004 | { 1005 | uint32_t u32CoarseChannelSelect; 1006 | { 1007 | boost::unique_lock oLock(m_oParameterMutex); 1008 | u32CoarseChannelSelect = (m_dFrequencyFs_Hz - m_pUI->doubleSpinBox_coarseChannelFrequencyIF_MHz->value()) * (m_u32SizeOfCoarseFFT_nSamp / 2) / (m_dFrequencyFs_Hz / 2); 1009 | } 1010 | 1011 | m_pKATCPClient->requestRoachSetCoarseChannelSelect(u32CoarseChannelSelect); 1012 | } 1013 | 1014 | void cRoachAcquistionControlWidget::slotSendCoarseChannelSelect_RF0() 1015 | { 1016 | uint32_t u32CoarseChannelSelect; 1017 | { 1018 | boost::unique_lock oLock(m_oParameterMutex); 1019 | double dFrequencyBaseband = m_dFrequencyRFChan0_MHz - m_pUI->doubleSpinBox_coarseChannelFrequencyRF0_MHz->value() + (m_dFrequencyFs_Hz / 4); 1020 | u32CoarseChannelSelect = dFrequencyBaseband * (m_u32SizeOfCoarseFFT_nSamp / 2) / (m_dFrequencyFs_Hz / 2); 1021 | } 1022 | 1023 | m_pKATCPClient->requestRoachSetCoarseChannelSelect(u32CoarseChannelSelect); 1024 | } 1025 | 1026 | void cRoachAcquistionControlWidget::slotSendCoarseChannelSelect_RF1() 1027 | { 1028 | uint32_t u32CoarseChannelSelect; 1029 | { 1030 | boost::unique_lock oLock(m_oParameterMutex); 1031 | double dFrequencyBaseband = m_dFrequencyRFChan1_MHz - m_pUI->doubleSpinBox_coarseChannelFrequencyRF1_MHz->value() + (m_dFrequencyFs_Hz / 4); 1032 | u32CoarseChannelSelect = dFrequencyBaseband * (m_u32SizeOfCoarseFFT_nSamp / 2) / (m_dFrequencyFs_Hz / 2); 1033 | } 1034 | 1035 | m_pKATCPClient->requestRoachSetCoarseChannelSelect(u32CoarseChannelSelect); 1036 | } 1037 | 1038 | void cRoachAcquistionControlWidget::slotSendCoarseFFTShiftMask() 1039 | { 1040 | m_pKATCPClient->requestRoachSetCoarseFFTShiftMask(m_pUI->spinBox_coarseFFTShiftMask->value()); 1041 | } 1042 | 1043 | void cRoachAcquistionControlWidget::slotSendADC0Attenuation() 1044 | { 1045 | m_pKATCPClient->requestRoachSetADC0Attenuation(m_pUI->doubleSpinBox_ADCChan0Attenuation->value() * 2); //Assume KATADC 0.5 dB per step 1046 | } 1047 | 1048 | void cRoachAcquistionControlWidget::slotSendADC1Attenuation() 1049 | { 1050 | m_pKATCPClient->requestRoachSetADC1Attenuation(m_pUI->doubleSpinBox_ADCChan1Attenuation->value() * 2); //Assume KATADC 0.5 dB per step 1051 | } 1052 | 1053 | void cRoachAcquistionControlWidget::slotToggleNoiseDiodeEnabled() 1054 | { 1055 | boost::unique_lock oLock(m_oParameterMutex); 1056 | m_pKATCPClient->requestRoachSetNoiseDiodeEnabled(!m_bNoiseDiodeEnabled); 1057 | } 1058 | 1059 | void cRoachAcquistionControlWidget::slotToggleNoiseDiodeDutyCycleEnabled() 1060 | { 1061 | boost::unique_lock oLock(m_oParameterMutex); 1062 | m_pKATCPClient->requestRoachSetNoiseDiodeDutyCycleEnabled(!m_bNoiseDiodeDutyCycleEnabled); 1063 | } 1064 | 1065 | void cRoachAcquistionControlWidget::slotSendNoiseDiodeDutyCycleOnDuration_nAccums() 1066 | { 1067 | m_pKATCPClient->requestRoachSetNoiseDiodeDutyCycleOnDuration(m_pUI->spinBox_noiseDiodeDutyCycleOnDuration_accums->value()); 1068 | } 1069 | 1070 | void cRoachAcquistionControlWidget::slotSendNoiseDiodeDutyCycleOnDuration_ms() 1071 | { 1072 | uint32_t u32NAccums; 1073 | { 1074 | boost::unique_lock oLock(m_oParameterMutex); 1075 | u32NAccums = boost::math::lround(m_pUI->spinBox_noiseDiodeDutyCycleOnDuration_ms->value() / (m_dSingleAccumulationLength_ms * m_u32AccumulationLength_nFrames) + 0.5); 1076 | } 1077 | 1078 | m_pKATCPClient->requestRoachSetNoiseDiodeDutyCycleOnDuration(u32NAccums); 1079 | } 1080 | 1081 | void cRoachAcquistionControlWidget::slotSendNoiseDiodeDutyCycleOffDuration_nAccums() 1082 | { 1083 | m_pKATCPClient->requestRoachSetNoiseDiodeDutyCycleOffDuration(m_pUI->spinBox_noiseDiodeDutyCycleOffDuration_accums->value()); 1084 | } 1085 | 1086 | void cRoachAcquistionControlWidget::slotSendNoiseDiodeDutyCycleOffDuration_ms() 1087 | { 1088 | uint32_t u32NAccums; 1089 | { 1090 | boost::unique_lock oLock(m_oParameterMutex); 1091 | u32NAccums = boost::math::lround(m_pUI->spinBox_noiseDiodeDutyCycleOffDuration_ms->value() / (m_dSingleAccumulationLength_ms * m_u32AccumulationLength_nFrames) + 0.5); 1092 | } 1093 | 1094 | m_pKATCPClient->requestRoachSetNoiseDiodeDutyCycleOffDuration(u32NAccums); 1095 | } 1096 | --------------------------------------------------------------------------------