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;
  }
}
示例#2
0
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" );
}
示例#3
0
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" );
}
示例#5
0
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() );
    }
  }
}