void BCI2000OutputFormat::Preflight( const SignalProperties& inProperties, const StateVector& ) const { Parameter( "SourceCh" ); switch( inProperties.Type() ) { case SignalType::int16: case SignalType::int32: case SignalType::float32: /* These types are OK */ break; default: bcierr << inProperties.Type().Name() << " data type unsupported for BCI2000 files" << endl; } }
void EDFFileWriter::Preflight( const SignalProperties& Input, SignalProperties& Output ) const { EDFFileWriterBase::Preflight( Input, Output ); if( Input.Type() != SignalType::int16 ) bcierr << "Signal data type must be int16 for EDF files" << endl; Parameter( "SubjectYearOfBirth" ); Parameter( "EquipmentID" ); Parameter( "TechnicianID" ); Parameter( "LabID" ); }
bool SignalProperties::Accommodates( const SignalProperties& sp ) const { if( sp.IsEmpty() ) return true; if( IsEmpty() ) return false; if( !SignalType::ConversionIsSafe( sp.Type(), Type() ) ) return false; if( Elements() < sp.Elements() ) return false; if( Elements() < sp.Elements() ) return false; return true; }
void EDFOutputFormat::Preflight( const SignalProperties& inProperties, const StateVector& inStatevector ) const { EDFOutputBase::Preflight( inProperties, inStatevector ); if( inProperties.Type() != SignalType::int16 ) bcierr << "Signal data type must be int16 for EDF files" << endl; Parameter( "SubjectYearOfBirth" ); Parameter( "EquipmentID" ); Parameter( "TechnicianID" ); Parameter( "LabID" ); Parameter( "SubjectName" ); }
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() ); } } }