diff --git a/src/starsphere/EinsteinRadioAdapter.cpp b/src/starsphere/EinsteinRadioAdapter.cpp index ae7e95a815fbf5c09c841369a7cfe85865e9d921..1df0a158f52b72a797a5e21ddf97ba3ac240fc23 100644 --- a/src/starsphere/EinsteinRadioAdapter.cpp +++ b/src/starsphere/EinsteinRadioAdapter.cpp @@ -22,7 +22,8 @@ const string EinsteinRadioAdapter::SharedMemoryIdentifier = "EinsteinRadio"; -EinsteinRadioAdapter::EinsteinRadioAdapter(BOINCClientAdapter *boincClient) +EinsteinRadioAdapter::EinsteinRadioAdapter(BOINCClientAdapter *boincClient) : + m_WUTemplatePowerSpectrum(POWERSPECTRUM_BINS, 0) { this->boincClient = boincClient; @@ -44,6 +45,8 @@ void EinsteinRadioAdapter::refresh() void EinsteinRadioAdapter::parseApplicationInformation() { + char spectrumArray[POWERSPECTRUM_BIN_BYTES + 1] = {0}; + // get updated application information string info = boincClient->applicationInformation(); @@ -52,24 +55,26 @@ void EinsteinRadioAdapter::parseApplicationInformation() // parse data into members // TODO: this is soon going to be replaced by true XML parsing! - if(8 != sscanf(info.c_str(), + if(9 != sscanf(info.c_str(), "<graphics_info>\n" - " <fraction_done>%lf</fraction_done>\n" - " <cpu_time>%lf</cpu_time>\n" " <skypos_rac>%lf</skypos_rac>\n" " <skypos_dec>%lf</skypos_dec>\n" " <dispersion>%lf</dispersion>\n" " <orb_radius>%lf</orb_radius>\n" " <orb_period>%lf</orb_period\n" - " <orb_phase>%lf</orb_phase>\n", - &m_WUFractionDone, - &m_WUCPUTime, + " <orb_phase>%lf</orb_phase>\n" + " <power_spectrum>%80c</power_spectrum>\n" + " <fraction_done>%lf</fraction_done>\n" + " <cpu_time>%lf</cpu_time>\n", &m_WUSkyPosRightAscension, &m_WUSkyPosDeclination, &m_WUDispersionMeasure, &m_WUTemplateOrbitalRadius, &m_WUTemplateOrbitalPeriod, - &m_WUTemplateOrbitalPhase)) + &m_WUTemplateOrbitalPhase, + spectrumArray, + &m_WUFractionDone, + &m_WUCPUTime)) { cerr << "Incompatible shared memory data encountered!" << endl; } @@ -77,6 +82,31 @@ void EinsteinRadioAdapter::parseApplicationInformation() // convert radians to degrees m_WUSkyPosRightAscension *= 180/PI; m_WUSkyPosDeclination *= 180/PI; + + // prepare power spectrum data + string spectrumString(spectrumArray); + if(spectrumString.length() == POWERSPECTRUM_BIN_BYTES) { + int spectrumBinValue; + istringstream spectrumBinStream; + // iterate over all bins + for(int i = 0, j = 0; i < POWERSPECTRUM_BIN_BYTES; i += 2, ++j) { + spectrumBinStream.str(spectrumString.substr(i, 2)); + if(spectrumBinStream) { + // convert hex bin value to integer + spectrumBinStream >> hex >> spectrumBinValue; + // store bin power value + m_WUTemplatePowerSpectrum.at(j) = (char) spectrumBinValue; + spectrumBinStream.clear(); + } + else { + cerr << "Premature end of spectrum stream encountered!" << endl; + break; + } + } + } + else { + cerr << "Invalid power spectrum data encountered!" << endl; + } } } } @@ -111,6 +141,11 @@ double EinsteinRadioAdapter::wuTemplateOrbitalPhase() const return m_WUTemplateOrbitalPhase; } +const vector<char>* EinsteinRadioAdapter::wuTemplatePowerSpectrum() const +{ + return &m_WUTemplatePowerSpectrum; +} + double EinsteinRadioAdapter::wuFractionDone() const { return m_WUFractionDone; diff --git a/src/starsphere/EinsteinRadioAdapter.h b/src/starsphere/EinsteinRadioAdapter.h index 0d0a514a5115023a0450b869eff1c98a8c1cbad5..04593a4391ef8f5fdde5337e86fcb05626ffebdb 100644 --- a/src/starsphere/EinsteinRadioAdapter.h +++ b/src/starsphere/EinsteinRadioAdapter.h @@ -22,12 +22,16 @@ #define EINSTEINRADIOADAPTER_H_ #include <string> +#include <sstream> +#include <iomanip> #include "BOINCClientAdapter.h" using namespace std; #define PI 3.14159265 +#define POWERSPECTRUM_BINS 40 +#define POWERSPECTRUM_BIN_BYTES 80 /** * \addtogroup starsphere Starsphere @@ -108,6 +112,13 @@ public: */ double wuTemplateOrbitalPhase() const; + /** + * \brief Retrieves the power spectrum of the currently active template + * + * \return The power spectrum of the currently active template + */ + const vector<char>* wuTemplatePowerSpectrum() const; + /** * \brief Retrieves the completion fraction of the currently active work unit * @@ -159,6 +170,9 @@ private: /// Initial orbital phase of the currently active template double m_WUTemplateOrbitalPhase; + /// Power spectrum of the currently active template + vector<char> m_WUTemplatePowerSpectrum; + /// The completion fraction of the active work unit double m_WUFractionDone; diff --git a/src/starsphere/StarsphereRadio.cpp b/src/starsphere/StarsphereRadio.cpp index ea13a19130ad1cd395b3eb56c9e06431f874a522..4c4162d71e3e94f4d2badc2d337246927766263e 100644 --- a/src/starsphere/StarsphereRadio.cpp +++ b/src/starsphere/StarsphereRadio.cpp @@ -20,17 +20,18 @@ #include "StarsphereRadio.h" -StarsphereRadio::StarsphereRadio() : Starsphere(), m_EinsteinAdapter(&m_BoincAdapter) +StarsphereRadio::StarsphereRadio() : + Starsphere(EinsteinRadioAdapter::SharedMemoryIdentifier), + m_EinsteinAdapter(&m_BoincAdapter) { m_WUDispersionMeasureValue = -1.0; m_PowerSpectrumCoordSystemList = 0; m_PowerSpectrumBinList = 0; - m_PowerSpectrumFreqBins = new vector<char>(40, 0); + m_PowerSpectrumFreqBins = 0; } StarsphereRadio::~StarsphereRadio() { - if(m_PowerSpectrumFreqBins) delete m_PowerSpectrumFreqBins; } void StarsphereRadio::initialize(const int width, const int height, const Resource *font, const bool recycle) @@ -129,7 +130,7 @@ void StarsphereRadio::refreshBOINCInformation() if(m_WUDispersionMeasureValue != m_EinsteinAdapter.wuDispersionMeasure()) { // we've got a new dispersion measure, update HUD - m_WUDispersionMeasureValue = m_EinsteinAdapter.wuSkyPosDeclination(); + m_WUDispersionMeasureValue = m_EinsteinAdapter.wuDispersionMeasure(); buffer << "DM: " << fixed << m_WUDispersionMeasureValue << " pc/cm3" << ends; m_WUDispersionMeasure = buffer.str(); buffer.str(""); @@ -261,15 +262,12 @@ void StarsphereRadio::generatePowerSpectrumBins(const int originX, const int ori // set pixel normalization factor for maximum bin height GLfloat normalizationFactor = 255.0 / (m_PowerSpectrumHeight - axesYOffset); - // TODO: use real FFT data -// ------test code - srand(time(NULL)); - for(int i=0; i<40; ++i) { - // set bin value to normalized pixel height - m_PowerSpectrumFreqBins->at(i) = (rand() % 10) * normalizationFactor; -// m_PowerSpectrumFreqBins->at(i) = 255 / normalizationFactor; + // fetch pointer to power spectrum data + m_PowerSpectrumFreqBins = m_EinsteinAdapter.wuTemplatePowerSpectrum(); + if(!m_PowerSpectrumFreqBins) { + cerr << "Power spectrum data currently unavailable!" << endl; + return; } -// ------test code // delete existing, create new (required for windoze) if(m_PowerSpectrumBinList) glDeleteLists(m_PowerSpectrumBinList, 1); @@ -281,9 +279,9 @@ void StarsphereRadio::generatePowerSpectrumBins(const int originX, const int ori // draw frequency bins glBegin(GL_LINES); // iterate over all bins - for(int i = 0; i < 40; ++i) { + for(int i = 0; i < POWERSPECTRUM_BINS; ++i) { // show potential candidates (power >= 100)... - if(m_PowerSpectrumFreqBins->at(i) >= m_PowerSpectrumHeight / 2.55) { + if(m_PowerSpectrumFreqBins->at(i) >= 100) { // ...in bright white glColor4f(1.0, 1.0, 1.0, 1.0); } @@ -296,7 +294,7 @@ void StarsphereRadio::generatePowerSpectrumBins(const int originX, const int ori offsetY + axesYOffset); // upper vertex glVertex2f(offsetX + axesXOffset + i*binXOffset, - offsetY + axesYOffset + m_PowerSpectrumFreqBins->at(i)); + offsetY + axesYOffset + m_PowerSpectrumFreqBins->at(i) / normalizationFactor); } glEnd(); diff --git a/src/starsphere/StarsphereRadio.h b/src/starsphere/StarsphereRadio.h index f478cb6d3e842e720153ac4bbcc9ec0afd598407..34424a021263d9602fc4f6d30222be85ad9f5439 100644 --- a/src/starsphere/StarsphereRadio.h +++ b/src/starsphere/StarsphereRadio.h @@ -131,7 +131,7 @@ private: GLuint m_PowerSpectrumBinList; /// Byte vector to hold the current power spectrum bin values - vector<char>* m_PowerSpectrumFreqBins; + const vector<char>* m_PowerSpectrumFreqBins; /// Power Spectrum configuration setting (width) GLfloat m_PowerSpectrumWidth;