#include "loadRef.h" LoadRefPulse::LoadRefPulse( int c, ProcParams* pp, QWidget* parentCP, QWidget* parent ) : QMainWindow( parentCP ) { // Set the name of the window. setObjectName( "Load Reference Pulse" ); setWindowTitle( "Load Reference Pulse" ); // Set the parameter to a member variable. channels = c; par = parent; pParams = pp; // Initialize the variable. width = 0; finishedLoading = false; clearingBoxes = false; size = 0; curValues = new float*[ channels ]; for( int m = 0; m < channels; ++m ) { curValues[m] = NULL; } // Connect the writeMsg signal to write to activity logs. connect( this, SIGNAL( writeMsg( QString, int ) ), parentCP, SLOT( writeToLog( QString, int ) ) ); // Connect the setChange signal to change the reference waveforms being used in the processing. connect( this, SIGNAL( setChange() ), par, SLOT( setWaveChange() ) ); // Create the group boxes and layouts for the elements. QGridLayout* topLayout = new QGridLayout; QGridLayout* bottomLayout = new QGridLayout; QGridLayout* chanLayout = new QGridLayout; QGridLayout* setLayout = new QGridLayout; QVBoxLayout* layout = new QVBoxLayout; QGroupBox* selectedPulse = new QGroupBox( tr( "Selected Reference Pulse" ) ); QGroupBox* newPulse = new QGroupBox( tr( "New Reference Pulse" ) ); QGroupBox* chanBox = new QGroupBox( tr( "Radar Channel" ) ); QGroupBox* newSet = new QGroupBox( tr( "New Reference Pulse Set" ) ); // Create the buttons. createNewPulse = new QPushButton( tr( "Create New Pulse" ) ); saveNewPulse = new QPushButton( tr( "Save Pulse" ) ); discardNewPulse = new QPushButton( tr( "Discard Pulse" ) ); acceptCurPulse = new QPushButton( tr( "Accept Pulses In Set" ) ); deletePulse = new QPushButton( tr( "Delete Current Pulse" ) ); loadFromFile = new QPushButton( tr( "Load Values From File" ) ); createNewSet = new QPushButton( tr( "Create New Set" ) ); deleteCurrSet = new QPushButton( tr( "Delete Current Set" ) ); saveNewSet = new QPushButton( tr( "Save Set" ) ); discardNewSet = new QPushButton( tr( "Discard Set" ) ); // Connect the buttons to functions. connect( createNewPulse, SIGNAL( clicked() ), this, SLOT( createPulse() ) ); connect( saveNewPulse, SIGNAL( clicked() ), this, SLOT( savePulse() ) ); connect( discardNewPulse, SIGNAL( clicked() ), this, SLOT( discardPulse() ) ); connect( acceptCurPulse, SIGNAL( clicked() ), this, SLOT( acceptSet() ) ); connect( deletePulse, SIGNAL( clicked() ), this, SLOT( deleteCurPulse() ) ); connect( loadFromFile, SIGNAL( clicked() ), this, SLOT( loadValues() ) ); connect( createNewSet, SIGNAL( clicked() ), this, SLOT( createSet() ) ); connect( deleteCurrSet, SIGNAL( clicked() ), this, SLOT( deleteSet() ) ); connect( saveNewSet, SIGNAL( clicked() ), this, SLOT( saveSet() ) ); connect( discardNewSet, SIGNAL( clicked() ), this, SLOT( discardSet() ) ); // Create the other elements. setSelect = new QComboBox( this ); pulseSelect = new QComboBox( this ); newPulseName = new QLineEdit( "", this ); newPulseWidth = new QLineEdit( "", this ); newPulseLength = new QLineEdit( "", this ); newPulseFreq = new QLineEdit( "", this ); chanSelect = new QComboBox( this ); widthSelect = new QComboBox( this ); freqSelect = new QComboBox( this ); newSetName = new QLineEdit( "", this ); newSetFreq = new QLineEdit( "", this ); newSetWidth = new QLineEdit( "", this ); // Connect the combo box to a function for when the index of the box is changed. connect( pulseSelect, SIGNAL( currentIndexChanged( int ) ), this, SLOT( setDisplayedPulse( int ) ) ); connect( chanSelect, SIGNAL( currentIndexChanged( int ) ), this, SLOT( changeChannelPulse( int ) ) ); connect( widthSelect, SIGNAL( currentIndexChanged( int ) ), this, SLOT( changeChannelWidthFreq() ) ); connect( freqSelect, SIGNAL( currentIndexChanged( int ) ), this, SLOT( changeChannelWidthFreq() ) ); connect( setSelect, SIGNAL( currentIndexChanged( int ) ), this, SLOT( changeSet() ) ); // Create the labels for the elements. setSelectLabel = new QLabel( tr( "Select Set" ) ); freqSelectLabel = new QLabel( tr( "Select Frequency (MHz):" ) ); pulseSelectLabel = new QLabel( tr( "Selected Reference Pulse:" ) ); newPulseNameLabel = new QLabel( tr( "New Pulse Name:" ) ); newPulseLengthLabel = new QLabel( tr( "New Pulse Length:" ) ); chanSelectLabel = new QLabel( tr( "Select Channel:" ) ); widthSelectLabel = new QLabel( tr( "Select Pulse Width (us):" ) ); newPulseWidthLabel = new QLabel( tr( "New Pulse Width (us):" ) ); newPulseFreqLabel = new QLabel( tr( "New Pulse Frequency (MHz):" ) ); newSetNameLabel = new QLabel( tr( "New Set Name:" ) ); newSetFreqLabel = new QLabel( tr( "New Set Frequency (MHz):" ) ); newSetWidthLabel = new QLabel( tr( "New Pulse Width (us):" ) ); // Disable the new reference pulse and set items. newPulseName->setEnabled( false ); newPulseWidth->setEnabled( false ); newPulseLength->setEnabled( false ); newPulseFreq->setEnabled( false ); saveNewPulse->setEnabled( false ); discardNewPulse->setEnabled( false ); loadFromFile->setEnabled( false ); newSetName->setEnabled( false ); newSetFreq->setEnabled( false ); newSetWidth->setEnabled( false ); saveNewSet->setEnabled( false ); discardNewSet->setEnabled( false ); // Set some fields to be read-only. newPulseWidth->setReadOnly( true ); newPulseFreq->setReadOnly( true ); newPulseLength->setReadOnly( true ); newSetFreq->setReadOnly( true ); newSetWidth->setReadOnly( true ); // Set the width of the first column for both layouts. Make the layouts look nicer. topLayout->setColumnMinimumWidth( 0, 200 ); bottomLayout->setColumnMinimumWidth( 0, 200 ); // Add the elements to the channel layout. chanLayout->addWidget( freqSelectLabel, 1, 0, Qt::AlignRight ); chanLayout->addWidget( freqSelect, 1, 1, 1, 2 ); chanLayout->addWidget( widthSelectLabel, 2, 0, Qt::AlignRight ); chanLayout->addWidget( widthSelect, 2, 1, 1, 2 ); chanLayout->addWidget( setSelectLabel, 3, 0, Qt::AlignRight ); chanLayout->addWidget( setSelect, 3, 1, 1, 2 ); chanLayout->addWidget( chanSelectLabel, 4, 0, Qt::AlignRight ); chanLayout->addWidget( chanSelect, 4, 1, 1, 2 ); chanLayout->addWidget( createNewSet, 5, 1 ); chanLayout->addWidget( deleteCurrSet, 5, 2 ); // Add the elements to the select pulse layout. topLayout->addWidget( pulseSelectLabel, 1, 0, Qt::AlignRight ); topLayout->addWidget( pulseSelect, 1, 1, 1, 2 ); topLayout->addWidget( createNewPulse, 2, 1 ); topLayout->addWidget( deletePulse, 2, 2 ); topLayout->addWidget( acceptCurPulse, 3, 1, 1, 2 ); // Add the elements to the new pulse layout. bottomLayout->addWidget( newPulseNameLabel, 1, 0, Qt::AlignRight ); bottomLayout->addWidget( newPulseName, 1, 1, 1, 2 ); bottomLayout->addWidget( newPulseFreqLabel, 2, 0, Qt::AlignRight ); bottomLayout->addWidget( newPulseFreq, 2, 1, 1, 2 ); bottomLayout->addWidget( newPulseWidthLabel, 3, 0, Qt::AlignRight ); bottomLayout->addWidget( newPulseWidth, 3, 1, 1, 2 ); bottomLayout->addWidget( newPulseLengthLabel, 4, 0, Qt::AlignRight ); bottomLayout->addWidget( newPulseLength, 4, 1, 1, 2 ); bottomLayout->addWidget( loadFromFile, 5, 1 ); bottomLayout->addWidget( discardNewPulse, 5, 2 ); bottomLayout->addWidget( saveNewPulse, 6, 1, 1, 2 ); // Add the elements to the new set layout. setLayout->addWidget( newSetNameLabel, 1, 0, Qt::AlignRight ); setLayout->addWidget( newSetName, 1, 1, 1, 2 ); setLayout->addWidget( newSetFreqLabel, 2, 0, Qt::AlignRight ); setLayout->addWidget( newSetFreq, 2, 1, 1, 2 ); setLayout->addWidget( newSetWidthLabel, 3, 0, Qt::AlignRight ); setLayout->addWidget( newSetWidth, 3, 1, 1, 2 ); setLayout->addWidget( saveNewSet, 4, 1 ); setLayout->addWidget( discardNewSet, 4, 2 ); // Add the layouts to the Group Boxes. selectedPulse->setLayout( topLayout ); newPulse->setLayout( bottomLayout ); chanBox->setLayout( chanLayout ); newSet->setLayout( setLayout ); // Add the group boxes to the main layout. layout->addWidget( chanBox ); layout->addWidget( selectedPulse ); layout->addWidget( newPulse ); layout->addWidget( newSet ); // Set the main layout. setCentralWidget( new QWidget() ); centralWidget()->setLayout( layout ); // Add the values to the channel combo box. for( int k = 0; k < channels; ++k ) { QString str = "Channel "; QString num; num.setNum( k + 1 ); str.append( num ); chanSelect->addItem( str ); } // Load in the reference pulses from the config file. loadFile(); // Only show the pulses for the current frequency and pulse width. // If no sets and pulses are present, then create a new set with the // a default pulse for each channel. showCorrectSets(); } LoadRefPulse::~LoadRefPulse() { } void LoadRefPulse::loadFile() { configFile = new QFile( "misc/ref_pulses.dat" ); if( configFile->open( QFile::ReadOnly ) ) { // Create a text stream to make reading in values easier. QTextStream stream( configFile ); // Read in the number of pulses and number of pulse widths. QString number; stream >> number; int pNumber = number.toInt(); // Read in the individual pulses. for( int i = 0; i < pNumber; ++i ) { // Read in the pulses and store them. QString name, freq, width, length, values; int counter = 0; values = ""; // Set the values string to nothing. stream >> name; // Read in the name of the pulse. stream >> freq; // Read in the frequency of the pulse. stream >> width; // Read in the width of the pulse. stream >> length; // Read in the length of the pulse. pFreqs.insert( name, freq ); // Place frequency into the map. pWidths.insert( name, width ); // Place the width into the map. pLengths.insert( name, length ); // Place length into the map. // Check if the frequency and width have been added to the combo boxes yet. // If not, add them. if( !freqs.contains( freq ) ) { freqs.insert( freq, 0 ); freqSelect->addItem( freq ); } if( !widths.contains( width ) ) { widths.insert( width, 0 ); widthSelect->addItem( width ); } // Convert the length string into a number. int pLength = length.toInt(); // Read in the number of values specified. for( int j = 0; j < pLength-1; ++j ) { QString tmp; stream >> tmp; values.append( tmp + " " ); } QString tmp; stream >> tmp; values.append( tmp ); pValues.insert( name, values ); // Place values into the map. counter++; // Increment counter. } // Read in the sets. QString setNum; stream >> setNum; for( int k = 0; k < setNum.toInt(); ++k ) { QString name, freq, width; QString* chVals = new QString[ MAXCHANNEL ]; stream >> name >> freq >> width; sFreqs.insert( name, freq ); // Place frequency into the map. sWidths.insert( name, width ); // Place width into the map. if( !freqs.contains( freq ) ) { freqs.insert( freq, 0 ); freqSelect->addItem( freq ); } if( !widths.contains( width ) ) { widths.insert( width, 0 ); widthSelect->addItem( width ); } for( int m = 0; m < MAXCHANNEL; ++m ) { QString tmp; stream >> tmp; chVals[m] = tmp; } sValues.insert( name, chVals ); // Place the values into the map. } } configFile->close(); /*// Add the pulse names to the combo box. QMapIterator< QString, QString > i( pFreqs ); while( i.hasNext() ) { i.next(); // Only add the pulse name if the pulse frequency and width match the currently selected frequency and width. if( ( pFreqs.value( i.key() ) == freqSelect->currentText() ) && ( pWidths.value( i.key() ) == widthSelect->currentText() ) ) { pulseSelect->addItem( i.key() ); } } // Add the set names to the combo box. QMapIterator< QString, QString > j( sFreqs ); while( j.hasNext() ) { j.next(); // Only add the pulse name if the pulse frequency and width match the currently selected frequency and width. if( ( sFreqs.value( j.key() ) == freqSelect->currentText() ) && ( sWidths.value( j.key() ) == widthSelect->currentText() ) ) { setSelect->addItem( j.key() ); } } // Set the first reference pulse in the set to be selected by default. setSelect->setCurrentIndex( 0 ); if( setSelect->currentText() != "" ) { QString* firstSetVals = sValues.value( setSelect->currentText() ); for( int n = 0; n < pulseSelect->count(); ++n ) { if( pulseSelect->itemText( n ) == firstSetVals[0] ) { pulseSelect->setCurrentIndex( n ); break; } } } // Accept the default set so that data processing can begin immediately. acceptSet();*/ } void LoadRefPulse::writeToFile() { if( configFile ) { delete configFile; configFile = NULL; } // Open the file for writing and start at the beginning. configFile = new QFile( "misc/ref_pulses.dat" ); if( configFile->open( QFile::WriteOnly | QFile::Truncate ) ) { // Create a text stream to make writing easier. QTextStream stream( configFile ); // Write the number of pulses. stream << pFreqs.count(); stream << "\n"; // Write out the information for each pulse. //for( int i = 0; i < pFreqs.count(); ++i ) QMapIterator< QString, QString > pulse( pFreqs ); while( pulse.hasNext() ) { pulse.next(); QString pulseName = pulse.key(); stream << pulseName << " "; stream << pFreqs.value( pulseName ) << " "; stream << pWidths.value( pulseName ) << " "; stream << pLengths.value( pulseName ) << " "; stream << pValues.value( pulseName ) << "\n"; } // Write the number of sets. stream << sFreqs.count(); stream << "\n"; // Write out the information for each set. //for( int j = 0; j < sFreqs.count(); ++j ) QMapIterator< QString, QString > set( sFreqs ); while( set.hasNext() ) { set.next(); QString setName = set.key(); stream << setName << " "; stream << sFreqs.value( setName ) << " "; stream << sWidths.value( setName ); // Write out the pulse name for each channel in the set. QString* names = sValues.value( setName ); for( int k = 0; k < MAXCHANNEL; ++k ) { stream << " " << names[k]; } stream << "\n"; } } configFile->close(); } void LoadRefPulse::savePulse() { // Check that the number of values is equal to the size and that all values are floats. // Also check that the new pulse elements are not empty. if( checkSizeValues( -1, SAVE ) && ( newPulseName->text() != "" ) && ( newPulseLength->text() != "" ) && ( newPulseValues != "" ) && ( newPulseFreq->text() != "" ) && ( !pFreqs.contains( newPulseName->text() ) ) ) { // Check that the number of values matches the frequency and pulse width. if( checkLength() ) { // Add the new pulse to the total list of pulses. pFreqs.insert( newPulseName->text(), newPulseFreq->text() ); pWidths.insert( newPulseName->text(), newPulseWidth->text() ); pLengths.insert( newPulseName->text(), newPulseLength->text() ); pValues.insert( newPulseName->text(), newPulseValues ); // See if the user want to use this pulse for every channel in the current set. QMessageBox* saveMsg = new QMessageBox( this ); saveMsg->setText( "Saving New Pulse" ); saveMsg->setInformativeText( "Do you want to use this pulse for every channel in the set? If yes, choose OK. If no, choose Cancel to only set for the current channel." ); saveMsg->addButton( QMessageBox::Yes ); saveMsg->addButton( QMessageBox::No ); saveMsg->setDefaultButton( QMessageBox::Yes ); int ret = saveMsg->exec(); // Wait for the window to close and grab the return value. // If the return value was OK, then set the pulse for every channel. if( ret == QMessageBox::Yes ) { // Get the set's selected pulses and change them. if( setSelect->currentText() != "" ) { QString* newSetVals = new QString[ MAXCHANNEL ]; for( int i = 0; i < MAXCHANNEL; ++i ) { newSetVals[i] = newPulseName->text(); } sValues.remove( setSelect->currentText() ); sValues.insert( setSelect->currentText(), newSetVals ); } else { emit writeMsg( "ERROR: No set selected.", NORMAL ); } } else { // Get the set's selected pulses and change only the current channel. if( setSelect->currentText() != "" ) { QString* setVals = sValues.value( setSelect->currentText() ); QString* newSetVals = new QString[ MAXCHANNEL ]; for( int l = 0; l < MAXCHANNEL; ++l ) { if( l == chanSelect->currentIndex() ) { newSetVals[l] = newPulseName->text(); } else { newSetVals[l] = setVals[l]; } } sValues.remove( setSelect->currentText() ); sValues.insert( setSelect->currentText(), newSetVals ); } else { emit writeMsg( "ERROR: No set selected.", NORMAL ); } } // Add the new pulse to the pulse combo box and make it selected. pulseSelect->addItem( newPulseName->text() ); pulseSelect->setCurrentIndex( pulseSelect->count() - 1 ); // Clear and disable the elements. discardPulse(); emit writeMsg( ">Saved a new reference pulse.", DEBUG ); } else { emit writeMsg( "ERROR: Length does not match frequency.", NORMAL ); } } else { // Error. emit writeMsg( ">ERROR: Cannot save reference pulse. Check that there are the correct amount of values in the pulse, that all values are uint32, there are no empty fields, and the new name does not match a current pulse's name.", NORMAL ); } } void LoadRefPulse::createPulse() { // Enable the new reference pulse items. newPulseName->setEnabled( true ); newPulseWidth->setEnabled( true ); newPulseLength->setEnabled( true ); newPulseFreq->setEnabled( true ); saveNewPulse->setEnabled( true ); discardNewPulse->setEnabled( true ); loadFromFile->setEnabled( true ); // Set the values of the new frequency and width fields. newPulseFreq->setText( freqSelect->currentText() ); newPulseWidth->setText( widthSelect->currentText() ); } void LoadRefPulse::discardPulse() { // Clear the values in the elements. newPulseName->clear(); newPulseWidth->clear(); newPulseLength->clear(); newPulseValues = ""; newPulseFreq->clear(); // Disable the new reference pulse items. newPulseName->setEnabled( false ); newPulseWidth->setEnabled( false ); newPulseLength->setEnabled( false ); newPulseFreq->setEnabled( false ); saveNewPulse->setEnabled( false ); discardNewPulse->setEnabled( false ); loadFromFile->setEnabled( false ); } void LoadRefPulse::acceptSet() { // First, make sure there is a set selected. if( setSelect->currentText() != "" ) { // Next, check that there are enough values for the given size. bool check = true; for( int i = 0; i < channels; ++i ) { if( !checkSizeValues( i, ACCEPT ) ) { QString chan; chan.setNum( i + 1 ); emit writeMsg( ">ERROR: Checking size and values for channel " + chan + "'s selected reference pulse.", NORMAL ); check = false; } } if( check ) { // Copy the values and size to the correct member variables. copyValues(); if( finishedLoading ) { // Emit signal that the set and reference waveforms have changed. emit setChange(); } // Close the window. this->close(); } else { // Error. emit writeMsg( ">ERROR: Cannot save reference pulse. Check that there are the correct amount of values in the pulse and that all values are floats.", NORMAL ); } } else { // Error. emit writeMsg( ">ERROR: No set selected.", NORMAL ); } } bool LoadRefPulse::checkSizeValues( int ch, int type ) { // Determine if this is checking values from a SAVE or ACCEPT command. QString vals; int length; if( type == SAVE ) { vals = newPulseValues; length = newPulseLength->text().toInt(); } else { QString* tmp = sValues.value( setSelect->currentText() ); QString pulseName = tmp[ ch ]; vals = pValues.value( pulseName ); length = pLengths.value( pulseName ).toInt(); } // Create a text stream to make things easier. QTextStream stream( &vals ); bool correct = true; // Bool to return. int counter = 0; // Counter while( !stream.atEnd() && ( counter < length ) ) { QString tmp; // Create a temp string variable. stream >> tmp; // Read value into temp. if( !isFloat( tmp.toStdString() ) ) // Check if the value is a float. { correct = false; } counter++; // Increment counter. } // Check if the corrent amount of values were read. if( !( counter == length ) ) { correct = false; } // Return the boolean. return correct; } bool LoadRefPulse::isFloat( std::string str ) { std::istringstream iss( str ); float f; iss >> std::noskipws >> f; return iss.eof() && !iss.fail(); } void LoadRefPulse::copyValues() { width = widthSelect->currentText().toDouble(); // The width of the pulse. frequency = freqSelect->currentText().toDouble(); // The frequency of the pulse. QString* allVals = sValues.value( setSelect->currentText() ); for( int i = 0; i < channels; ++i ) { // Create a text stream to make things easier. QString vals = pValues.value( allVals[i] ); QTextStream stream( &vals ); // Delete the object if it exists. if( curValues[i] ) { delete curValues[i]; curValues[i] = NULL; } // Create the new object. size = pLengths.value( allVals[i] ).toInt(); curValues[i] = new float[ size ]; for( int j = 0; j < size; ++j ) { QString tmp; // Create a temp string variable. stream >> tmp; // Read value into temp. curValues[i][j] = tmp.toFloat(); // Do the conversion. } } QString s; s.setNum( size ); emit writeMsg( "Size is: " + s, DEBUG ); } void LoadRefPulse::closeEvent( QCloseEvent* event ) { // Write every pulse to file. writeToFile(); event->accept(); } int LoadRefPulse::getSize() { return size; } float** LoadRefPulse::getValues() { return curValues; } void LoadRefPulse::setDisplayedPulse( int index ) { if( finishedLoading && !clearingBoxes ) { // Set the channel's selected pulse in the set. if( setSelect->currentText() != "" ) { QString* setVals = sValues.value( setSelect->currentText() ); setVals[ chanSelect->currentIndex() ] = pulseSelect->itemText( index ); sValues.remove( setSelect->currentText() ); sValues.insert( setSelect->currentText(), setVals ); } } } void LoadRefPulse::changeChannelPulse( int index ) { if( !clearingBoxes ) { // Get the new channel's selected pulse based on the set. if( setSelect->currentText() != "" ) { QString* setVals = sValues.value( setSelect->currentText() ); for( int n = 0; n < pulseSelect->count(); ++n ) { if( pulseSelect->itemText( n ) == setVals[index] ) { pulseSelect->setCurrentIndex( n ); break; } } } } } void LoadRefPulse::deleteCurPulse() { // First, get the name of the current pulse and delete it from the combo box, if not the default pulse. QString pulseName = pulseSelect->currentText(); QString pN, pF, pW, pV; pF.setNum( pParams->sFrequency ); pW.setNum( pParams->tau * 1000000.0 ); pN = "Base_Pulse_"; pN.append( pF ); pN.append( "_" ); pN.append( pW ); // Only delete if not the default pulse. if( pulseName != pN ) { pulseSelect->removeItem( pulseSelect->currentIndex() ); pulseSelect->setCurrentIndex( 0 ); // Second, remove the pulse from the map of pulses. pFreqs.remove( pulseName ); pWidths.remove( pulseName ); pLengths.remove( pulseName ); pValues.remove( pulseName ); // Third, remove the pulse from any of the sets. for( int i = 0; i < setSelect->count(); ++i ) { if( setSelect->itemText( i ) != "" ) { QString* setVals = sValues.value( setSelect->itemText( i ) ); for( int j = 0; j < MAXCHANNEL; ++j ) { if( setVals[j] == pulseName ) { setVals[ j ] = pulseSelect->currentText(); } } sValues.remove( setSelect->currentText() ); sValues.insert( setSelect->currentText(), setVals ); } else { emit writeMsg( "ERROR: No set selected.", NORMAL ); } } } else { emit writeMsg( "ERROR: Cannot delete default pulse.", NORMAL ); } } void LoadRefPulse::loadValues() { // Create the file dialog to open the binary file. QFileDialog fDialog(this); fDialog.setFileMode( QFileDialog::ExistingFile ); fDialog.setNameFilter( tr( "Binary Files (*.bin)" ) ); // If the user clicks OK on a file, enter the if statement. if( fDialog.exec() ) { // Get the absolute path to the file. QStringList pathList = fDialog.selectedFiles(); QString path = pathList[0]; //emit writeMsg( path, DEBUG ); // Create the file descriptor and convert the path to a char array. FILE* inputFile; char name[ 100 ]; sprintf( name, "%s", path.toStdString().c_str() ); // Open the file as read only and binary, then check if the file opened properly. inputFile = fopen( name, "rb" ); if( inputFile == NULL ) // File did not open properly. { emit writeMsg( ">ERROR: Cannot open file.", NORMAL ); } else // File opened without issues. { // Create some variables to store values and strings. uint16_t val; QString allValues; QString len; int numValues = 0; // Read from the file until the end is reached. while( fread( &val, sizeof( uint16_t ), 1, inputFile ) == 1 ) { // Store the uint16 value read from file into a QString. QString tmp; tmp.setNum( val ); // Append the value and a space into the QString variable that will hold all of the values. allValues.append( tmp ); allValues.append( " " ); // Increment the counter for number of values read in from the file. numValues++; } // Close the file. fclose( inputFile ); // Set the new pulse length and values objects with the new QStrings. len.setNum( numValues ); newPulseLength->setText( len ); newPulseValues = allValues; } } } void LoadRefPulse::changeChannelWidthFreq() { if( finishedLoading && !clearingBoxes ) { // Clear the names from the combo boxes. clearingBoxes = true; pulseSelect->clear(); setSelect->clear(); clearingBoxes = false; // Add the set names to the combo box. QMapIterator< QString, QString > j( sFreqs ); while( j.hasNext() ) { j.next(); // Only add the pulse name if the pulse frequency and width match the currently selected frequency and width. if( ( sFreqs.value( j.key() ) == freqSelect->currentText() ) && ( sWidths.value( j.key() ) == widthSelect->currentText() ) ) { setSelect->addItem( j.key() ); } } // Add the pulse names to the combo box. QMapIterator< QString, QString > i( pFreqs ); while( i.hasNext() ) { i.next(); // Only add the pulse name if the pulse frequency and width match the currently selected frequency and width. if( ( pFreqs.value( i.key() ) == freqSelect->currentText() ) && ( pWidths.value( i.key() ) == widthSelect->currentText() ) ) { pulseSelect->addItem( i.key() ); } } // Set the first reference pulse in the set to be selected by default. setSelect->setCurrentIndex( 0 ); if( setSelect->currentText() != "" ) { QString* firstSetVals = sValues.value( setSelect->currentText() ); for( int n = 0; n < pulseSelect->count(); ++n ) { if( pulseSelect->itemText( n ) == firstSetVals[0] ) { pulseSelect->setCurrentIndex( n ); break; } } } } } bool LoadRefPulse::checkLength() { return true; } void LoadRefPulse::createSet() { // Enable the elements. newSetName->setEnabled( true ); newSetFreq->setEnabled( true ); newSetWidth->setEnabled( true ); saveNewSet->setEnabled( true ); discardNewSet->setEnabled( true ); // Set the values of the freq and width to match the selected values. newSetFreq->setText( freqSelect->currentText() ); newSetWidth->setText( widthSelect->currentText() ); } void LoadRefPulse::discardSet() { // Clear the elements. newSetName->clear(); newSetFreq->clear(); newSetWidth->clear(); // Disable the elements. newSetName->setEnabled( false ); newSetFreq->setEnabled( false ); newSetWidth->setEnabled( false ); saveNewSet->setEnabled( false ); discardNewSet->setEnabled( false ); } void LoadRefPulse::saveSet() { // Save the new set information into the maps. QString setName = newSetName->text(); sFreqs.insert( setName, newSetFreq->text() ); sWidths.insert( setName, newSetWidth->text() ); // If the set is not in the combo box, add it. bool contains = false; for( int k = 0; k < setSelect->count(); ++k ) { if( setSelect->itemText( k ) == newSetName->text() ) { contains = true; } } if( !contains ) // Set is new. { setSelect->addItem( newSetName->text() ); // If the frequency is not in the combo box, add it. contains = false; for( int i = 0; i < freqSelect->count(); ++i ) { if( freqSelect->itemText( i ) == newSetFreq->text() ) { contains = true; freqSelect->setCurrentIndex( i ); } } if( !contains ) { freqSelect->addItem( newSetFreq->text() ); freqSelect->setCurrentIndex( freqSelect->count() - 1 ); } // If the width is not in the combo box, add it. contains = false; for( int j = 0; j < widthSelect->count(); ++j ) { if( widthSelect->itemText( j ) == newSetWidth->text() ) { contains = true; widthSelect->setCurrentIndex( j ); } } if( !contains ) { widthSelect->addItem( newSetWidth->text() ); widthSelect->setCurrentIndex( widthSelect->count() - 1 ); } // Set the default pulses to use for each channel. QString defPulse = "Zeros_"; defPulse.append( newSetFreq->text() ); defPulse.append( "_" ); defPulse.append( newSetWidth->text() ); // See if the default pulse has been created before already. if( !pFreqs.contains( defPulse ) ) { // Create the default pulse and add it to the list of pulses. pFreqs.insert( defPulse, newSetFreq->text() ); pWidths.insert( defPulse, newSetWidth->text() ); pValues.insert( defPulse, basePulseZeros() ); QString pL; pL.setNum( basePulseLength() ); pLengths.insert( defPulse, pL ); pulseSelect->addItem( defPulse ); } // Set the pulse for each channel and add to the values map. QString* vals = new QString[ MAXCHANNEL ]; for( int m = 0; m < MAXCHANNEL; ++m ) { vals[m] = defPulse; } sValues.insert( setName, vals ); // Make the new set the selected set. setSelect->setCurrentIndex( setSelect->count() - 1 ); // Set the zero pulse to be selected in the combo box. for( int z = 0; z < pulseSelect->count(); ++z ) { if( pulseSelect->itemText( z ) == defPulse ) { pulseSelect->setCurrentIndex( z ); } } // Clear the elements and disable them. discardSet(); } else { emit writeMsg( "ERROR: Set name already exists.", NORMAL ); } } void LoadRefPulse::deleteSet() { // Get the name of the current set and remove it from the set maps. QString setName = setSelect->currentText(); QString sN, sF, sW, pN, pF, pW, pL, pV; sF.setNum( pParams->sFrequency ); sW.setNum( pParams->tau * 1000000.0 ); sN = "Default_Set_"; sN.append( sF ); sN.append( "_" ); sN.append( sW ); // Only delete if not the default set. if( setName != sN ) { sFreqs.remove( setName ); sWidths.remove( setName ); sValues.remove( setName ); // Remove the set from the set combo box. for( int i = 0; i < setSelect->count(); ++i ) { if( setName == setSelect->itemText( i ) ) { setSelect->removeItem( i ); } } // Make the first left in the combo box the selected set. setSelect->setCurrentIndex( 0 ); // Display the information for the new selected set. changeSet(); } else { emit writeMsg( "ERROR: Cannot delete default set.", NORMAL ); } } void LoadRefPulse::changeSet() { if( !clearingBoxes ) { // Make sure there is a set selected. if( setSelect->currentText() != "" ) { // Get the array of values for the selected set. QString* firstSetVals = sValues.value( setSelect->currentText() ); // For each pulse in the combo box, see if it matches the pulse for channel 1 of the set. for( int n = 0; n < pulseSelect->count(); ++n ) { // If it matches, make that pulse the selected pulse. if( pulseSelect->itemText( n ) == firstSetVals[0] ) { pulseSelect->setCurrentIndex( n ); break; } } } } } double LoadRefPulse::getFreq() { return frequency; } double LoadRefPulse::getWidth() { return width; } QString LoadRefPulse::basePulseValues() { QString values = ""; int refLen = basePulseLength(); float bw = pParams->f1 - pParams->f0; float chirp_rate = bw / pParams->tau; // Create the time and reference variables. for( int i = 0; i < refLen; ++i ) { float tTime = i / pParams->sFrequency; float val = cos( 2 * M_PI * ( pParams->f0 * tTime + ( 0.5 * chirp_rate * tTime * tTime ) ) ); float hannW = 0.5 - ( 0.5 * cos( 2 * M_PI * i / ( refLen - 1 ) ) ); val = val * hannW; QString v; v.setNum( val ); values.append( v ); values.append( " " ); } return values; } QString LoadRefPulse::basePulseZeros() { QString values = ""; QString zero; zero.setNum( 0 ); int refLen = basePulseLength(); for( int i = 0; i < refLen; ++i ) { values.append( zero ); values.append( " " ); } return values; } int LoadRefPulse::basePulseLength() { return ( pParams->tau * pParams->sFrequency ) + 1; } void LoadRefPulse::showCorrectSets() { // Create QStrings for the frequency and width. QString fr, wid; fr.setNum( pParams->sFrequency / 1000000.0 ); wid.setNum( pParams->tau * 1000000.0 ); // Set the combo boxes for the frequency and width. clearingBoxes = true; freqSelect->clear(); freqSelect->addItem( fr ); freqSelect->setCurrentIndex( 0 ); widthSelect->clear(); widthSelect->addItem( wid ); widthSelect->setCurrentIndex( 0 ); clearingBoxes = false; // See if there is a set that matches the frequency and width. // Add the set names to the combo box. QMapIterator< QString, QString > j( sFreqs ); while( j.hasNext() ) { j.next(); // Only add the pulse name if the pulse frequency and width match the currently selected frequency and width. if( ( sFreqs.value( j.key() ) == freqSelect->currentText() ) && ( sWidths.value( j.key() ) == widthSelect->currentText() ) ) { setSelect->addItem( j.key() ); } } // Check to see if there were any sets added to the combo box. if( setSelect->count() != 0 ) { // Add the pulse names to the combo box. QMapIterator< QString, QString > i( pFreqs ); while( i.hasNext() ) { i.next(); // Only add the pulse name if the pulse frequency and width match the currently selected frequency and width. if( ( pFreqs.value( i.key() ) == freqSelect->currentText() ) && ( pWidths.value( i.key() ) == widthSelect->currentText() ) ) { pulseSelect->addItem( i.key() ); } } // Check to see if there were any pulses added to the combo box. if( pulseSelect->count() != 0 ) { // Set the first reference pulse in the set to be selected by default. setSelect->setCurrentIndex( 0 ); if( setSelect->currentText() != "" ) { QString* firstSetVals = sValues.value( setSelect->currentText() ); for( int n = 0; n < pulseSelect->count(); ++n ) { if( pulseSelect->itemText( n ) == firstSetVals[0] ) { pulseSelect->setCurrentIndex( n ); break; } } } } else // No pulses, so create a default pulse and use it for the values. { // New default pulse for this frequency and width. QString pN, pF, pW, pV, pL; pF.setNum( pParams->sFrequency ); pW.setNum( pParams->tau * 1000000.0 ); pL.setNum( basePulseLength() ); pN = "Base_Pulse_"; pN.append( pF ); pN.append( "_" ); pN.append( pW ); pV = basePulseValues(); // Add the pulse to the maps. pFreqs.insert( pN, pF ); pWidths.insert( pN, pW ); pValues.insert( pN, pV ); pLengths.insert( pN, pL ); // Add the pulse to the pulse combo box and make it the current item. pulseSelect->addItem( pN ); pulseSelect->setCurrentIndex( 0 ); // Set the new pulse as the one used for each channel in the set. QString* sV = new QString[ MAXCHANNEL ]; for( int i = 0; i < MAXCHANNEL; ++i ) { sV[i] = pN; } sValues.remove( setSelect->currentText() ); sValues.insert( setSelect->currentText(), sV ); } } else // No sets, so create a default set and default pulses. { QString sN, sF, sW, pN, pF, pW, pL, pV; sF.setNum( pParams->sFrequency ); sW.setNum( pParams->tau * 1000000.0 ); sN = "Default_Set_"; sN.append( sF ); sN.append( "_" ); sN.append( sW ); // Set pulse variables and add to maps. pF.setNum( pParams->sFrequency ); pW.setNum( pParams->tau * 1000000.0 ); pL.setNum( basePulseLength() ); pN = "Base_Pulse_"; pN.append( pF ); pN.append( "_" ); pN.append( pW ); pV = basePulseValues(); // Add the pulse variables to the maps. pFreqs.insert( pN, pF ); pWidths.insert( pN, pW ); pValues.insert( pN, pV ); pLengths.insert( pN, pL ); // Add the pulse to the combo box and show it. pulseSelect->addItem( pN ); pulseSelect->setCurrentIndex( 0 ); // Set the set values. QString* sV = new QString[ MAXCHANNEL ]; for( int j = 0; j < MAXCHANNEL; ++j ) { sV[j] = pN; } // Add the set variables to the maps. sFreqs.insert( sN, sF ); sWidths.insert( sN, sW ); sValues.insert( sN, sV ); // Add the set to the combo box and show it. setSelect->addItem( sN ); setSelect->setCurrentIndex( 0 ); } // So that the processing can begin immediately. acceptSet(); // We have finished loading. finishedLoading = true; }