void TSWFilter::Preflight( const SignalProperties& Input, SignalProperties& Output ) const { #if 0 if( Parameter( "YMean" ) != 0 ) bciout << "YMean should be set to zero for Slow Waves" << endl; if( Parameter( "YGain" ) < 300 || Parameter( "YGain" ) > 400 ) bciout << "YGain should be set to 327.68 for Slow Waves" << endl; #endif Parameter( "FeedbackEnd" ); State( itiStateName ); if( Parameter( "SWOutChList" )->NumValues() != Parameter( "SWInChList" )->NumValues() ) bcierr << "The number of entries in SWOutChList must match that in SWInChList" << endl; for( int i = 0; i < Parameter( "SWInChList" )->NumValues(); ++i ) PreflightCondition( Parameter( "SWInChList" )( i ) > 0 && Parameter( "SWInChList" )( i ) <= Input.Channels() ); for( int i = 0; i < Parameter( "SWOutChList" )->NumValues(); ++i ) PreflightCondition( Parameter( "SWOutChList" )( i ) > 0 && Parameter( "SWOutChList" )( i ) <= Input.Channels() ); PreflightCondition( Parameter( "Tc" ).InSampleBlocks() >= 0.0 ); PreflightCondition( Parameter( "SpatialFilteredChannels" ) == Input.Channels() ); Output = SignalProperties( Input.Channels(), 1 ); Output.SetName( "SWFiltered" ); }
void Normalizer::Preflight( const SignalProperties& Input, SignalProperties& Output ) const { if( Parameter( "NormalizerOffsets" )->NumValues() < Input.Channels() ) bcierr << "The number of entries in the NormalizerOffsets parameter must match " << "the number of input channels" << endl; if( Parameter( "NormalizerGains" )->NumValues() < Input.Channels() ) bcierr << "The number of entries in the NormalizerGains parameter must match " << "the number of input channels" << endl; ParamRef Adaptation = Parameter( "Adaptation" ); if( Adaptation->NumValues() < Input.Channels() ) bcierr << "The number of entries in the Adaptation parameter must match " << "the number of input channels" << endl; bool adaptation = false; for( int channel = 0; channel < Input.Channels() && channel < Adaptation->NumValues(); ++channel ) adaptation |= ( Adaptation( channel ) != none ); if( adaptation ) { GenericSignal preflightSignal( Input ); string UpdateTrigger = Parameter( "UpdateTrigger" ); if( !UpdateTrigger.empty() ) Expression( UpdateTrigger ).Evaluate( &preflightSignal ); ParamRef BufferConditions = Parameter( "BufferConditions" ); if( BufferConditions->NumColumns() > Input.Channels() ) bcierr << "The number of columns in the BufferConditions parameter " << "may not exceed the number of input channels" << endl; // Evaluate all expressions to test for validity. for( int row = 0; row < BufferConditions->NumRows(); ++row ) for( int col = 0; col < BufferConditions->NumColumns(); ++col ) Expression( BufferConditions( row, col ) ).Evaluate( &preflightSignal ); double bufferSize = Parameter( "BufferLength" ).InSampleBlocks(); if( bufferSize < 1 ) bciout << "The BufferLength parameter specifies a zero-sized buffer" << endl; } // Request output signal properties: Output = Input; // Describe output: if( adaptation ) Output.ValueUnit().SetOffset( 0 ).SetGain( 1 ).SetSymbol( "" ) .SetRawMin( -2 ).SetRawMax( 2 ); }
void ComplexDemodulator::Preflight( const SignalProperties& Input, SignalProperties& Output ) const { ParamRef DemodulatorFrequencies = Parameter( "DemodulatorFrequencies" ); bool error = false; for( int i = 0; i < DemodulatorFrequencies->NumValues(); ++i ) { double frequency = MeasurementUnits::ReadAsFreq( DemodulatorFrequencies( i ) ); error |= ( frequency < 0 ); error |= ( frequency > 0.5 ); } if( error ) bcierr << "DemodulatorFrequencies must be greater 0 and less than half the " << "sampling rate " << "(currently " << Parameter( "SamplingRate" ) << "Hz)" << endl; double FrequencyResolution = MeasurementUnits::ReadAsFreq( Parameter( "FrequencyResolution" ) ); PreflightCondition( FrequencyResolution > 0 ); // Request output signal properties: Output = SignalProperties( Input.Channels(), DemodulatorFrequencies->NumValues(), SignalType::float32 ); }
void ARFilter::Initialize( const SignalProperties& Input, const SignalProperties& /*Output*/ ) { int windowLength = MeasurementUnits::ReadAsTime( Parameter( "WindowLength" ) ) * Parameter( "SampleBlockSize" ); mBuffer.clear(); mBuffer.resize( Input.Channels(), DataVector( 0.0, windowLength ) ); mOutputType = Parameter( "OutputType" ); mDetrend = Parameter( "Detrend" ); mMEMPredictor.SetModelOrder( Parameter( "ModelOrder" ) ); switch( mOutputType ) { case SpectralAmplitude: case SpectralPower: { float firstBinCenter = MeasurementUnits::ReadAsFreq( Parameter( "FirstBinCenter" ) ), lastBinCenter = MeasurementUnits::ReadAsFreq( Parameter( "LastBinCenter" ) ), binWidth = MeasurementUnits::ReadAsFreq( Parameter( "BinWidth" ) ); int outputElements = ::floor( ( lastBinCenter - firstBinCenter + eps ) / binWidth + 1 ); mTransferSpectrum .SetFirstBinCenter( firstBinCenter ) .SetBinWidth( binWidth ) .SetNumBins( outputElements ) .SetEvaluationsPerBin( Parameter( "EvaluationsPerBin" ) ); } break; case ARCoefficients: break; } }
void TFBArteCorrection::Preflight( const SignalProperties& inSignalProperties, SignalProperties& outSignalProperties ) const { for( int i = 0; i < Parameter( "ArteChList" )->NumValues(); ++i ) { PreflightCondition( Parameter( "ArteChList" )( i ) >= 0 ); PreflightCondition( Parameter( "ArteChList" )( i ) <= inSignalProperties.Channels() ); } outSignalProperties = inSignalProperties; outSignalProperties.SetName( "Artifact Filtered" ); }
// ************************************************************************** // Function: Preflight // Purpose: Checks parameters for availability and consistency with // input signal properties; requests minimally needed properties for // the output signal; checks whether resources are available. // Parameters: Input and output signal properties pointers. // Returns: N/A // ************************************************************************** void FIRFilter::Preflight( const SignalProperties& inSignalProperties, SignalProperties& outSignalProperties ) const { // Parameter consistency checks: Existence/Ranges and mutual Ranges. Parameter( "SamplingRate" ); PreflightCondition( Parameter( "FIRFilteredChannels" ) == Parameter( "FIRFilterKernal" )->NumRows() ); // PreflightCondition( // Parameter( "SampleBlockSize" ) == Parameter( "FIRFilterKernal" )->GetNumValuesDimension2() ); PreflightCondition( Parameter( "FIRFilterKernal" )->NumRows() <= MAX_M ); PreflightCondition( Parameter( "FIRFilterKernal" )->NumColumns() <= MAX_N ); // Resource availability checks. /* The FIR filter seems not to depend on external resources. */ // Input signal checks. PreflightCondition( Parameter( "FIRFilteredChannels" ) <= inSignalProperties.Channels() ); // Requested output signal properties. if( Parameter( "Integration" ) == 0 ) { PreflightCondition( Parameter( "FIRFilterKernal" )->NumColumns() == ( Parameter( "FIRWindows" ) -1 ) * Parameter( "SampleBlockSize" ) + 1 ); outSignalProperties = SignalProperties( inSignalProperties.Channels(), Parameter( "SampleBlockSize" ) ); } else { PreflightCondition( Parameter( "FIRFilterKernal" )->NumColumns() <= ( Parameter( "FIRWindows" ) -1 ) * Parameter( "SampleBlockSize" ) + 1 ); outSignalProperties = SignalProperties( inSignalProperties.Channels(), 1 ); } }
void EDFOutputFormat::Initialize( const SignalProperties& inProperties, const StateVector& inStatevector ) { EDFOutputBase::Initialize( inProperties, inStatevector ); // Adapt marker channels to EDF conventions. for( size_t i = inProperties.Channels(); i < Channels().size(); ++i ) { Channels()[ i ].DigitalMinimum = 0; Channels()[ i ].DigitalMaximum = static_cast<int>( Channels()[ i ].DigitalMaximum - 1 ) & 0x7fff; Channels()[ i ].PhysicalMinimum = Channels()[ i ].DigitalMinimum; Channels()[ i ].PhysicalMaximum = Channels()[ i ].DigitalMaximum; } }
void EDFFileWriter::Initialize( const SignalProperties& Input, const SignalProperties& Output ) { EDFFileWriterBase::Initialize( Input, Output ); // Adapt marker channels to EDF conventions. for( size_t i = Input.Channels(); i < Channels().size(); ++i ) { Channels()[ i ].DigitalMinimum = 0; Channels()[ i ].DigitalMaximum = int( Channels()[ i ].DigitalMaximum - 1 ) & 0x7fff; Channels()[ i ].PhysicalMinimum = Channels()[ i ].DigitalMinimum; Channels()[ i ].PhysicalMaximum = Channels()[ i ].DigitalMaximum; } }
void CustomFIRFilter::Initialize( const SignalProperties& Input, const SignalProperties& /*Output*/ ) { mBuffer.clear(); ParamRef FIRCoefficients = Parameter( "FIRCoefficients" ); int filterLength = FIRCoefficients->NumValues(); mFilter.resize( filterLength, 0.0 ); for( int sample = 0; sample < filterLength; ++sample ) mFilter[sample] = FIRCoefficients( sample ); int bufferLength = filterLength + Input.Elements() - 1; mBuffer.resize( Input.Channels(), DataVector( 0.0, bufferLength ) ); }
void AlignmentFilter::Initialize( const SignalProperties& Input, const SignalProperties& /*Output*/ ) { mPrevSample.clear(); mWeightPrev.clear(); mWeightCur.clear(); // Do we want to align the samples in time ? mAlign = ( Parameter( "AlignChannels" ) == 1 ); if( mAlign ) { mPrevSample.resize( Input.Channels(), 0.0 ); mWeightPrev.resize( Input.Channels(), 0.0 ); mWeightCur.resize( Input.Channels(), 1.0 ); // Calculate weight values for linear interpolation if we do not use the default value. if( Parameter( "SourceChTimeOffset" )->NumValues() > 0 ) { for( int i = 0; i < Input.Channels(); ++i ) // get original channel position { mWeightPrev[ i ] = Parameter( "SourceChTimeOffset" )( i ); mWeightCur[ i ] = 1.0 - mWeightPrev[ i ]; } } // If we do use the default value, assume that all sampled channels are evenly distributed in time. else { float delta = 1.0 / Input.Channels(); for( int i = 0; i < Input.Channels(); ++i ) // get original channel position { mWeightPrev[ i ] = delta * i; mWeightCur[ i ] = 1.0 - mWeightPrev[ i ]; } } } }
void BufferedADC::Preflight( const SignalProperties&, SignalProperties& Output ) const { if( Parameter( "SourceBufferSize" ).InSampleBlocks() < 2 ) bcierr << "The SourceBufferSize parameter must be greater or" << " equal 2 sample blocks." << endl; State( "SourceTime" ); State( "Running" ); mAcquisitionProperties = Output; this->OnPreflight( mAcquisitionProperties ); Output = mAcquisitionProperties; int numStateChannels = 0; for( int ch = 0; ch < Output.Channels(); ++ch ) { bool isStateChannel = ( *Output.ChannelLabels()[ch].c_str() == StateMark ); if( numStateChannels && !isStateChannel ) bcierr_ << "State channels must be located at the end of the channel list"; else if( isStateChannel ) ++numStateChannels; } Output.SetChannels( Output.Channels() - numStateChannels ); }
void AverageDisplay::Preflight( const SignalProperties& Input, SignalProperties& Output ) const { PreflightCondition( Parameter( "AvgDisplayCh" )->NumColumns() >= 2 ); for( int i = 0; i < Parameter( "AvgDisplayCh" )->NumRows(); ++i ) PreflightCondition ( Parameter( "AvgDisplayCh" )( i, 0 ) > 0 && Parameter( "AvgDisplayCh" )( i, 0 ) <= Input.Channels() ); PreflightCondition( Parameter( "SamplingRate" ) > 0 ); PreflightCondition( Input.Elements() > 0 ); State( "TargetCode" ); Output = Input; }
void Normalizer::Initialize( const SignalProperties& Input, const SignalProperties& /*Output*/ ) { mOffsets.clear(); mGains.clear(); delete mpUpdateTrigger; mpUpdateTrigger = NULL; mBufferConditions.clear(); mDataBuffers.clear(); ParamRef Adaptation = Parameter( "Adaptation" ), NormalizerOffsets = Parameter( "NormalizerOffsets" ), NormalizerGains = Parameter( "NormalizerGains" ); mAdaptation.clear(); mDoAdapt = false; for( int channel = 0; channel < Input.Channels(); ++channel ) { mOffsets.push_back( NormalizerOffsets( channel ) ); mGains.push_back( NormalizerGains( channel ) ); mAdaptation.push_back( int( Adaptation( channel ) ) ); mDoAdapt |= ( Adaptation( channel ) != none ); } if( mDoAdapt ) { string UpdateTrigger = Parameter( "UpdateTrigger" ); if( !UpdateTrigger.empty() ) mpUpdateTrigger = new Expression( UpdateTrigger ); size_t bufferSize = static_cast<size_t>( Parameter( "BufferLength" ).InSampleBlocks() * Input.Elements() ); ParamRef BufferConditions = Parameter( "BufferConditions" ); mBufferConditions.resize( BufferConditions->NumColumns() ); for( int col = 0; col < BufferConditions->NumColumns(); ++col ) for( int row = 0; row < BufferConditions->NumRows(); ++row ) mBufferConditions[ col ].push_back( Expression( BufferConditions( row, col ) ) ); mDataBuffers.resize( BufferConditions->NumColumns(), vector<RingBuffer>( BufferConditions->NumRows(), RingBuffer( bufferSize ) ) ); bcidbg << "Allocated " << mDataBuffers.size() << "x" << ( mDataBuffers.empty() ? 0 : mDataBuffers[ 0 ].size() ) << " data buffers of size " << bufferSize << "." << endl; } }
void SpatialFilter::Preflight( const SignalProperties& Input, SignalProperties& Output ) const { // Parameter/Input consistency. if( Input.Channels() != Parameter( "SpatialFilter" )->NumColumns() ) bcierr << "The input signal's number of channels must match " << "the number of columns in the SpatialFilter parameter" << endl; // Output signal description. Output = Input; Output.SetChannels( 0 ).SetChannels( Parameter( "SpatialFilter" )->NumRows() ); if( !Parameter( "SpatialFilter" )->RowLabels().IsTrivial() ) for( int i = 0; i < Parameter( "SpatialFilter" )->NumRows(); ++i ) Output.ChannelLabels()[ i ] = Parameter( "SpatialFilter" )->RowLabels()[ i ]; }
void FFTFilter::Preflight( const SignalProperties& Input, SignalProperties& Output ) const { for( int i = 0; i < Parameter( "FFTInputChannels" )->NumValues(); ++i ) { int channelIndex = Input.ChannelIndex( Parameter( "FFTInputChannels" )( i ) ); if( channelIndex < 0 || channelIndex >= Input.Channels() ) bcierr << "Invalid channel specification \"" << Parameter( "FFTInputChannels" )( i ) << "\" in FFTInputChannels, evaluates to " << channelIndex << endl; } bool fftRequired = ( ( int )Parameter( "FFTOutputSignal" ) != eInput || ( int )Parameter( "VisualizeFFT" ) ) && ( Parameter( "FFTInputChannels" )->NumValues() > 0 ); if( fftRequired ) { if( mFFT.LibAvailable() ) { FFTLibWrapper preflightFFT; int fftWindowLength = Parameter( "SampleBlockSize" ) * MeasurementUnits::ReadAsTime( Parameter( "FFTWindowLength" ) ); if( !preflightFFT.Initialize( fftWindowLength ) ) bcierr << "Requested parameters are not supported by FFT library" << endl; } else bcierr << "The FFT Filter could not find the " << mFFT.LibName() << " library. " << "For legal reasons, this library is not part of the BCI2000 distribution. " << "Please download the latest version of fftw3.dll from " << "http://www.fftw.org/install/windows.html" << endl; } if( int( Parameter( "VisualizeFFT" ) ) ) { SignalProperties temp; DetermineSignalProperties( temp, ePower ); } Output = Input; DetermineSignalProperties( Output, Parameter( "FFTOutputSignal" ) ); }
void FeedbackDemoTask::OnPreflight( const SignalProperties& Input ) const { Parameter( "WindowHeight" ); Parameter( "WindowWidth" ); Parameter( "WindowLeft" ); Parameter( "WindowTop" ); if( RGBColor( Parameter( "CursorColor" ) ) == RGBColor::NullColor ) bcierr << "Invalid RGB value in CursorColor" << endl; if( MeasurementUnits::ReadAsTime( Parameter( "FeedbackDuration" ) ) <= 0 ) bcierr << "FeedbackDuration must be greater 0" << endl; if( Input.IsEmpty() ) bcierr << "Requires at least one entry in control signal" << endl; if( Input.Channels() > 1 ) bciout << "Will ignore additional channels in control signal" << endl; }
void FFTFilter::Preflight( const SignalProperties& Input, SignalProperties& Output ) const { for( int i = 0; i < Parameter( "FFTInputChannels" )->NumValues(); ++i ) { double channelIndex = Input.ChannelIndex( Parameter( "FFTInputChannels" )( i ) ); if( channelIndex < 0 || channelIndex >= Input.Channels() ) bcierr << "Invalid channel specification \"" << Parameter( "FFTInputChannels" )( i ) << "\" in FFTInputChannels, evaluates to " << channelIndex << endl; } bool fftRequired = ( int( Parameter( "FFTOutputSignal" ) ) != eInput || int( Parameter( "VisualizeFFT" ) ) ) && ( Parameter( "FFTInputChannels" )->NumValues() > 0 ); if( fftRequired ) { if( mFFT.LibAvailable() ) { RealFFT preflightFFT; int fftWindowLength = static_cast<int>( Input.Elements() * Parameter( "FFTWindowLength" ).InSampleBlocks() ); if( !preflightFFT.Initialize( fftWindowLength ) ) bcierr << "Requested parameters are not supported by FFT library" << endl; } else bcierr << "The FFT Filter could not find the " << mFFT.LibName() << " library." << endl; } if( int( Parameter( "VisualizeFFT" ) ) || int( Parameter( "FFTOutputSignal" ) ) == ePower ) { SignalProperties temp( Input ); DetermineSignalProperties( temp, ePower ); } Output = Input; DetermineSignalProperties( Output, Parameter( "FFTOutputSignal" ) ); }
void AlignmentFilter::Preflight( const SignalProperties& Input, SignalProperties& Output ) const { // Check the SourceChTimeOffset; only check if we do not use the default value. if( Parameter( "SourceChTimeOffset" )->NumValues() > 0 ) { // We need to have as many entries in SourceChTimeOffset as we have digitized channels: if( Parameter( "SourceChTimeOffset" )->NumValues() < Input.Channels() ) bcierr << "If not empty, the number of entries in SourceChTimeOffset must" << " match the number of input channels." << endl; // Each value in SourceChTimeOffset has to be >= 0 and < 1: for( int i = 0; i < Parameter( "SourceChTimeOffset" )->NumValues(); ++i ) if( Parameter( "SourceChTimeOffset" )( i ) < 0 || Parameter( "SourceChTimeOffset" )( i ) > 1 ) bcierr << "Values in SourceChTimeOffset must be between 0 and 1." << endl; } // Requested output signal properties. Output = Input; }
void P3TemporalFilter::Preflight( const SignalProperties& Input, SignalProperties& Output ) const { // Required states. State( "Running" ); State( "StimulusCode" ); State( "StimulusType" ); OptionalState( "StimulusBegin" ); float outputSamples = MeasurementUnits::ReadAsTime( Parameter( "EpochLength" ) ); outputSamples *= Input.Elements(); outputSamples = ::ceil( outputSamples ); // Requested output signal properties. Output = Input; Output.SetChannels( Input.Channels() ) .SetElements( outputSamples ) .SetType( SignalType::float32 ) .ElementUnit().SetRawMin( 0 ) .SetRawMax( outputSamples - 1 ); }
void ComplexDemodulator::Initialize( const SignalProperties& Input, const SignalProperties& Output ) { float FrequencyResolution = MeasurementUnits::ReadAsFreq( Parameter( "FrequencyResolution" ) ); size_t numCoefficients = ::floor( 1.0 / FrequencyResolution ) + 1; ParamRef DemodulatorFrequencies = Parameter( "DemodulatorFrequencies" ); mCoefficients.clear(); mCoefficients.resize( DemodulatorFrequencies->NumValues(), vector<complex<double> >( numCoefficients ) ); for( int i = 0; i < DemodulatorFrequencies->NumValues(); ++i ) { double freq = MeasurementUnits::ReadAsFreq( DemodulatorFrequencies( i ) ); for( size_t j = 0; j < numCoefficients; ++j ) mCoefficients[ i ][ j ] = polar( 0.5 / numCoefficients, freq * j * 2.0 * M_PI ); } mSignalBuffer.clear(); mSignalBuffer.resize( Input.Channels(), vector<double>( numCoefficients ) ); }
void RDAClientADC::OnPreflight( SignalProperties& Output ) const { // Resource availability and parameter consistency checks. RDA::Connection preflightConnection; int numSignalChannels = 0, numMarkerChannels = 0, numOutputChannels = 0; preflightConnection.Open( Parameter( "HostName" ) ); if( preflightConnection ) { const RDA::Info& info = preflightConnection.Info(); bool goodOffsets = true, goodGains = true; numSignalChannels = info.numChannels; string matchMessage = " parameter must match the number of channels" " in the recording software"; if( Parameter( "AddMarkerChannel" ) != 0 ) { numMarkerChannels = 1; matchMessage += " plus one marker channel"; } numOutputChannels = numSignalChannels + numMarkerChannels; if( Parameter( "SourceCh" ) != numOutputChannels ) bcierr << "The SourceCh " << matchMessage << " (" << numOutputChannels << ") "; if( Parameter( "SourceChOffset" )->NumValues() != numOutputChannels ) bcierr << "The number of values in the SourceChOffset" << matchMessage << " (" << numOutputChannels << ") "; else for( int i = 0; i < numSignalChannels; ++i ) goodOffsets &= ( Parameter( "SourceChOffset" )( i ) == 0 ); if( !goodOffsets ) bcierr << "The SourceChOffset values for the first " << numSignalChannels << " channels " << "must be 0"; if( Parameter( "SourceChGain" )->NumValues() != numOutputChannels ) bcierr << "The number of values in the SourceChGain" << matchMessage << " (" << numOutputChannels << ") "; else for( int i = 0; i < numSignalChannels; ++i ) { double gain = info.channelResolutions[ i ]; double prmgain = Parameter( "SourceChGain")( i ); bool same = ( 1e-3 > ::fabs( prmgain - gain ) / ( gain ? gain : 1.0 ) ); goodGains &= same; if ( !same ) bciout << "The RDA server says the gain of" << " channel " << i+1 << " is " << gain << " whereas the corresponding value in the" << " SourceChGain parameter is " << prmgain; } if( !goodGains ) bcierr << "The SourceChGain values for the first " << numSignalChannels << " channels " << "must match the channel resolutions settings " << "in the recording software"; if( info.samplingInterval < Limits( info.samplingInterval ).epsilon() ) bcierr << "The recording software reports an infinite sampling rate " << "-- make sure it shows a running signal in its window"; else { double sourceSamplingRate = 1e6 / info.samplingInterval; if( Parameter( "SamplingRate" ).InHertz() != sourceSamplingRate ) bcierr << "The SamplingRate parameter must match " << "the setting in the recording software " << "(" << sourceSamplingRate << ")"; // Check whether block sizes are sub-optimal. int sampleBlockSize = Parameter( "SampleBlockSize" ), sourceBlockSize = static_cast<int>( info.blockDuration / info.samplingInterval ); if( sampleBlockSize % sourceBlockSize != 0 ) bcierr << "System block size is " << sampleBlockSize << ", must be equal to " << "or a multiple of the RDA server's block size, which is " << sourceBlockSize; } } // Requested output signal properties. #if RDA_FLOAT Output = SignalProperties( numOutputChannels + 1, Parameter( "SampleBlockSize" ), SignalType::float32 ); #else bciwarn << "You are using the 16 bit variant of the RDA protocol, which is" << " considered unreliable. Switching to float is recommended" << endl; Output = SignalProperties( numOutputChannels + 1, Parameter( "SampleBlockSize" ), SignalType::int16 ); #endif // RDA_FLOAT Output.ChannelLabels()[Output.Channels() - 1] = StateMark + string( "RDAMarkers" ); }
void LinearClassifier::Preflight( const SignalProperties& Input, SignalProperties& Output ) const { // Determine the classifier matrix format: int controlSignalChannels = 0; const ParamRef& Classifier = Parameter( "Classifier" ); if( Classifier->NumColumns() != 4 ) bcierr << "Classifier parameter must have 4 columns " << "(input channel, input element, output channel, weight)" << endl; else { for( int row = 0; row < Classifier->NumRows(); ++row ) { if( Classifier( row, 2 ) < 1 ) bcierr << "Output channels must be positive integers" << endl; float ch = Input.ChannelIndex( Classifier( row, 0 ) ); if( ch < 0 ) bcierr << DescribeEntry( row, 0 ) << " points to negative input index" << endl; else if( ::floor( ch ) > Input.Channels() ) bcierr << "Channel specification in " << DescribeEntry( row, 0 ) << " exceeds number of input channels" << endl; if( ::fmod( ch, 1.0f ) > 1e-2 ) bciout << "Channel specification in physical units: " << DescribeEntry( row, 0 ) << " does not exactly meet a single channel" << endl; float el = Input.ElementIndex( Classifier( row, 1 ) ); if( el < 0 ) bcierr << DescribeEntry( row, 1 ) << " points to negative input index" << endl; if( ::floor( el ) > Input.Elements() ) bcierr << "Element (bin) specification in " << DescribeEntry( row, 1 ) << " exceeds number of input elements" << endl; if( ::fmod( el, 1.0f ) > 1e-2 ) bciout << "Element (bin) specification in physical units: " << DescribeEntry( row, 1 ) << " does not exactly meet a single element" << endl; int outputChannel = Classifier( row, 2 ); controlSignalChannels = max( controlSignalChannels, outputChannel ); } } // Requested output signal properties. Output = SignalProperties( controlSignalChannels, 1, Input.Type() ); // Output description. Output.ChannelUnit() = Input.ChannelUnit(); Output.ValueUnit().SetRawMin( Input.ValueUnit().RawMin() ) .SetRawMax( Input.ValueUnit().RawMax() ); float secsPerBlock = Parameter( "SampleBlockSize" ) / Parameter( "SamplingRate" ); Output.ElementUnit().SetOffset( 0 ).SetGain( secsPerBlock ).SetSymbol( "s" ); int visualizationTime = Output.ElementUnit().PhysicalToRaw( "15s" ); Output.ElementUnit().SetRawMin( 0 ).SetRawMax( visualizationTime - 1 ); }
void EDFFileWriterBase::Initialize( const SignalProperties& Input, const SignalProperties& Output ) { FileWriterBase::Initialize( Input, Output ); mChannels.clear(); // Enter brain signal channels into the channel list. int typeCode = GDF::float64::Code; switch( Input.Type() ) { case SignalType::int16: typeCode = GDF::int16::Code; break; case SignalType::int32: typeCode = GDF::int32::Code; break; case SignalType::float24: case SignalType::float32: typeCode = GDF::float32::Code; break; } float digitalMin = Input.Type().Min(), digitalMax = Input.Type().Max(); // GDF 1.25 uses int64 for digital min and max. if( digitalMin < numeric_limits<GDF::int64::ValueType>::min() ) digitalMin = numeric_limits<GDF::int64::ValueType>::min(); if( digitalMax > numeric_limits<GDF::int64::ValueType>::max() ) digitalMax = numeric_limits<GDF::int64::ValueType>::max(); ChannelInfo channel; channel.TransducerType = Parameter( "TransducerType" ); channel.PhysicalDimension = Parameter( "SignalUnit" ); channel.SamplesPerRecord = Parameter( "SampleBlockSize" ); channel.DataType = typeCode; channel.DigitalMinimum = digitalMin; channel.DigitalMaximum = digitalMax; for( int i = 0; i < Input.Channels(); ++i ) { if( i < Parameter( "ChannelNames" )->NumValues() ) channel.Label = Parameter( "ChannelNames" )( i ); else { ostringstream oss; oss << "Ch" << i + 1; channel.Label = oss.str(); } ostringstream filtering; if( OptionalParameter( "FilterEnabled", 0 ) == 1 ) filtering << "HP:" << Parameter( "FilterHighPass" ) << "LP:" << Parameter( "FilterLowPass" ); if( OptionalParameter( "NotchEnabled", 0 ) == 1 ) filtering << "N:" << ( Parameter( "NotchHighPass" ) + Parameter( "NotchLowPass" ) ) / 2.0; channel.Filtering = filtering.str(); channel.PhysicalMinimum = Parameter( "SourceChGain" )( i ) * ( digitalMin + Parameter( "SourceChOffset" )( i ) ); channel.PhysicalMaximum = Parameter( "SourceChGain" )( i ) * ( digitalMax + Parameter( "SourceChOffset" )( i ) ); mChannels.push_back( channel ); } // Marker channels to represent states. mStateNames.clear(); ChannelInfo markerChannel; markerChannel.TransducerType = "Marker"; markerChannel.PhysicalDimension = ""; markerChannel.SamplesPerRecord = 1; markerChannel.DataType = GDF::int16::Code; for( int i = 0; i < States->Size(); ++i ) { static string statesToIgnore[] = { "Running", "Recording" }; bool ignoreCurrentState = false; class State& state = ( *States )[ i ]; for( size_t i = 0; i < sizeof( statesToIgnore ) / sizeof( *statesToIgnore ) && !ignoreCurrentState; ++i ) ignoreCurrentState |= ( statesToIgnore[ i ] == state.Name() ); if( !ignoreCurrentState ) { double digitalMinimum = -1, digitalMaximum = 1 << state.Length(); markerChannel.Label = state.Name(); // DigitalMinimum and DigitalMaximum should be outside the range of actually // occurring values. markerChannel.DigitalMinimum = digitalMinimum; markerChannel.DigitalMaximum = digitalMaximum; markerChannel.PhysicalMinimum = digitalMinimum; markerChannel.PhysicalMaximum = digitalMaximum; Channels().push_back( markerChannel ); mStateNames.push_back( state.Name() ); } } }
MatlabEngine::DoubleMatrix::DoubleMatrix( const SignalProperties& inProperties ) : vector<vector<double> >( 1, vector<double>( 2 ) ) { ( *this )[ 0 ][ 0 ] = inProperties.Channels(); ( *this )[ 0 ][ 1 ] = inProperties.Elements(); }