Class: RColumn

Inherits:
Object
  • Object
show all
Defined in:
datavyu_api.rb

Overview

Ruby implementation of Datavyu column.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeRColumn

Returns a new instance of RColumn



336
337
338
# File 'datavyu_api.rb', line 336

def initialize()
  self.hidden = false
end

Instance Attribute Details

#arglistArray<String>

Returns names of codes for cell in this column, excluding onset, offset, and ordinal

Returns:

  • (Array<String>)

    names of codes for cell in this column, excluding onset, offset, and ordinal



332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
# File 'datavyu_api.rb', line 332

class RColumn

  attr_accessor :name, :type, :cells, :arglist, :old_args, :dirty, :db_var, :hidden

  def initialize()
    self.hidden = false
  end

  # Validate code name. Replace non-alphanumeric characters
  # with underscores and prepend an underscore if the code
  # starts with a number.
  # @param name string to validate
  # @return [String] validated code name
  # @since 1.3.6
  def self.sanitize_codename(name)
    sanitized = name.gsub(/(\W)+/, '').downcase
    sanitized.gsub!(/(^\d{1})/, '_\\1')
    sanitized
  end

  def convert_argname(arg)
    RColumn.sanitize_codename(arg)
  end

  # @note This function is not for general use.
  # Creates the cell object in the Variable object.
  # @param newcells (required): Array of cells coming from the database via get_column
  # @param arglist (required): Array of the names of the arguments from the database
  def set_cells(newcells, arglist)
    print_debug "Setting cells"
    @cells = Array.new
    @arglist = Array.new
    arglist.each do |arg|
      # Regex to delete any character not a-z,0-9,or _
      print_debug arg
      @arglist << RColumn.sanitize_codename(arg)
    end
    if !newcells.nil?
      ord = 0
      newcells.each do |cell|
        ord += 1
        c = RCell.new
        c.onset = cell.getOnset
        c.offset = cell.getOffset
        c.db_cell = cell
        c.parent = @name
        vals = Array.new
        if cell.getVariable.getRootNode.type == Argument::Type::MATRIX
          for val in cell.getCellValue().getArguments
            vals << val.toString
          end
        else
          vals << cell.getCellValue().toString
        end
        c.set_args(vals, @arglist)
        c.ordinal = ord
        @cells << c
      end
    end
  end

  # Creates a new, blank cell at the end of this variable's cell array.
  # If a template cell is provided, copies over onset and offset times and code values for any matching code names.
  # @param cell [RCell] template cell
  # @return [RCell] Reference to the cell that was just created.  Modify the cell using this reference.
  # @example
  #   trial = get_column("trial")
  #   new_cell = trial.new_cell()
  #   new_cell.onset = 1000
  #   set_column(trial)
  def new_cell(cell = nil)
    c = RCell.new
    c.set_args('', @arglist)
    if(cell.nil?)
      c.onset = 0
      c.offset = 0
      c.ordinal = 0
    else
      c.onset = cell.onset
      c.offset = cell.offset
      self.arglist.each do |code|
        c.change_code(code, cell.get_arg(code)) if cell.arglist.include?(code)
      end
    end
    c.parent = @name
    @cells << c
    return c
  end
  alias :make_new_cell :new_cell
  alias :create_cell :new_cell

  # Sorts cells and saves column's cells by ascending onset times.
  # @return nil
  def sort_cells()
    cells.sort! { |a, b| a.onset <=> b.onset }
  end

  # Changes the name of a code. Updates the name for all cells in the column
  # @param old_name the name of the argument you want to change
  # @param new_name the name you want to change old_name to
  # @return nil
  def change_code_name(old_name, new_name)
    i = @old_args.index(old_name)
    @old_args[i] = new_name

    # Sanitize code
    old_name = RColumn.sanitize_codename(old_name)

    i = @arglist.index(old_name)
    @arglist[i] = new_name
    for cell in @cells
      cell.change_code_name(i, new_name)
    end

    @dirty = true
  end
  alias :change_arg_name :change_code_name

  # Add a code to this column. Updates all cells in column with new code.
  # @param [String] name the name of the new code
  # @return nil
  def add_code(name)
    @old_args << name
    san_name = RColumn.sanitize_codename(name)

    @arglist << san_name
    for cell in @cells
      cell.add_arg(san_name)
    end

    @dirty = true
  end
  alias :add_arg :add_code

  # Remove a code from this column. Updates all cells in column.
  # @param [String] name the name of the code to remove
  # @return nil
  def remove_code(name)
    @old_args.delete(name)

    san_name = RColumn.sanitize_codename(name)
    @arglist.delete(san_name)

    for cell in @cells
      cell.remove_arg(san_name)
    end

    @dirty = true
  end
  alias :remove_arg :remove_code

  # Set hidden state of this column
  # @param value [true, false] true to hide column in spreadsheet, false to show
  # @return nil
  def set_hidden(value)
    @hidden = value
  end

  # Resamples the cells of this column using given step size.
  # Optionally can specify the start and end time-points.
  # @param [Integer] step step size to resample with, in milliseconds
  # @param [Hash] opts options
  # @option opts [String] :column_name (self.name) name of returned column
  # @option opts [Integer] :start_time (earliest onset) time to start resampling from, in milliseconds
  # @option opts [Integer] :stop_time (latest offset) time to stop resampling at, in milliseconds
  # @return [RColumn] new column with resampled cells
  # @note Undefined behavior for columns whose cells overlap with each other.
  # @since 1.3.6
  def resample(step, opts={})
    @resample_defaults = {
      :column_name => self.name,
      :start_time => :earliest,
      :stop_time => :latest
    }

    opts = @resample_defaults.merge(opts)
    if opts[:start_time] == :earliest
      opts[:start_time] = @cells.map(&:onset).min
    end
    if opts[:stop_time] == :latest
      opts[:stop_time] = @cells.map(&:offset).max
    end

    # Construct new column
    ncol = new_column(opts[:column_name], self.arglist)
    # Construct new cells spanning range.
    ( (opts[:start_time])..(opts[:stop_time]) ).step(step) do |time|
      ncell = ncol.new_cell
      ncell.onset = time
      ncell.offset = time + step - 1

      # Find overlapping cells from self in this time region
      overlap_cells = self.cells.select{ |x| x.overlaps_cell(ncell) }
      # if overlap_cells.empty?
      #   puts "no source cell for time #{time}"
      #   next
      # end
      next if overlap_cells.empty? # no source cell

      # Map each to their intersecting region and find the one with the largest duration.
      sorted_by_intersection =  overlap_cells.sort do |x, y|
        r1 = x.overlapping_region(ncell)
        d1 = r1.last - r1.first

        r2 = y.overlapping_region(ncell)
        d2 = r2.last - r2.first

        d2 <=> d1 # largest first
      end
      winner = sorted_by_intersection.first

      ncell.arglist.each do |code|
        ncell.change_code(code, winner.get_code(code))
      end
      # p ncol.cells.size
    end
    return ncol
  end
end

#cellsArray<RCell>

Returns list of cells in this column

Returns:

  • (Array<RCell>)

    list of cells in this column



332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
# File 'datavyu_api.rb', line 332

class RColumn

  attr_accessor :name, :type, :cells, :arglist, :old_args, :dirty, :db_var, :hidden

  def initialize()
    self.hidden = false
  end

  # Validate code name. Replace non-alphanumeric characters
  # with underscores and prepend an underscore if the code
  # starts with a number.
  # @param name string to validate
  # @return [String] validated code name
  # @since 1.3.6
  def self.sanitize_codename(name)
    sanitized = name.gsub(/(\W)+/, '').downcase
    sanitized.gsub!(/(^\d{1})/, '_\\1')
    sanitized
  end

  def convert_argname(arg)
    RColumn.sanitize_codename(arg)
  end

  # @note This function is not for general use.
  # Creates the cell object in the Variable object.
  # @param newcells (required): Array of cells coming from the database via get_column
  # @param arglist (required): Array of the names of the arguments from the database
  def set_cells(newcells, arglist)
    print_debug "Setting cells"
    @cells = Array.new
    @arglist = Array.new
    arglist.each do |arg|
      # Regex to delete any character not a-z,0-9,or _
      print_debug arg
      @arglist << RColumn.sanitize_codename(arg)
    end
    if !newcells.nil?
      ord = 0
      newcells.each do |cell|
        ord += 1
        c = RCell.new
        c.onset = cell.getOnset
        c.offset = cell.getOffset
        c.db_cell = cell
        c.parent = @name
        vals = Array.new
        if cell.getVariable.getRootNode.type == Argument::Type::MATRIX
          for val in cell.getCellValue().getArguments
            vals << val.toString
          end
        else
          vals << cell.getCellValue().toString
        end
        c.set_args(vals, @arglist)
        c.ordinal = ord
        @cells << c
      end
    end
  end

  # Creates a new, blank cell at the end of this variable's cell array.
  # If a template cell is provided, copies over onset and offset times and code values for any matching code names.
  # @param cell [RCell] template cell
  # @return [RCell] Reference to the cell that was just created.  Modify the cell using this reference.
  # @example
  #   trial = get_column("trial")
  #   new_cell = trial.new_cell()
  #   new_cell.onset = 1000
  #   set_column(trial)
  def new_cell(cell = nil)
    c = RCell.new
    c.set_args('', @arglist)
    if(cell.nil?)
      c.onset = 0
      c.offset = 0
      c.ordinal = 0
    else
      c.onset = cell.onset
      c.offset = cell.offset
      self.arglist.each do |code|
        c.change_code(code, cell.get_arg(code)) if cell.arglist.include?(code)
      end
    end
    c.parent = @name
    @cells << c
    return c
  end
  alias :make_new_cell :new_cell
  alias :create_cell :new_cell

  # Sorts cells and saves column's cells by ascending onset times.
  # @return nil
  def sort_cells()
    cells.sort! { |a, b| a.onset <=> b.onset }
  end

  # Changes the name of a code. Updates the name for all cells in the column
  # @param old_name the name of the argument you want to change
  # @param new_name the name you want to change old_name to
  # @return nil
  def change_code_name(old_name, new_name)
    i = @old_args.index(old_name)
    @old_args[i] = new_name

    # Sanitize code
    old_name = RColumn.sanitize_codename(old_name)

    i = @arglist.index(old_name)
    @arglist[i] = new_name
    for cell in @cells
      cell.change_code_name(i, new_name)
    end

    @dirty = true
  end
  alias :change_arg_name :change_code_name

  # Add a code to this column. Updates all cells in column with new code.
  # @param [String] name the name of the new code
  # @return nil
  def add_code(name)
    @old_args << name
    san_name = RColumn.sanitize_codename(name)

    @arglist << san_name
    for cell in @cells
      cell.add_arg(san_name)
    end

    @dirty = true
  end
  alias :add_arg :add_code

  # Remove a code from this column. Updates all cells in column.
  # @param [String] name the name of the code to remove
  # @return nil
  def remove_code(name)
    @old_args.delete(name)

    san_name = RColumn.sanitize_codename(name)
    @arglist.delete(san_name)

    for cell in @cells
      cell.remove_arg(san_name)
    end

    @dirty = true
  end
  alias :remove_arg :remove_code

  # Set hidden state of this column
  # @param value [true, false] true to hide column in spreadsheet, false to show
  # @return nil
  def set_hidden(value)
    @hidden = value
  end

  # Resamples the cells of this column using given step size.
  # Optionally can specify the start and end time-points.
  # @param [Integer] step step size to resample with, in milliseconds
  # @param [Hash] opts options
  # @option opts [String] :column_name (self.name) name of returned column
  # @option opts [Integer] :start_time (earliest onset) time to start resampling from, in milliseconds
  # @option opts [Integer] :stop_time (latest offset) time to stop resampling at, in milliseconds
  # @return [RColumn] new column with resampled cells
  # @note Undefined behavior for columns whose cells overlap with each other.
  # @since 1.3.6
  def resample(step, opts={})
    @resample_defaults = {
      :column_name => self.name,
      :start_time => :earliest,
      :stop_time => :latest
    }

    opts = @resample_defaults.merge(opts)
    if opts[:start_time] == :earliest
      opts[:start_time] = @cells.map(&:onset).min
    end
    if opts[:stop_time] == :latest
      opts[:stop_time] = @cells.map(&:offset).max
    end

    # Construct new column
    ncol = new_column(opts[:column_name], self.arglist)
    # Construct new cells spanning range.
    ( (opts[:start_time])..(opts[:stop_time]) ).step(step) do |time|
      ncell = ncol.new_cell
      ncell.onset = time
      ncell.offset = time + step - 1

      # Find overlapping cells from self in this time region
      overlap_cells = self.cells.select{ |x| x.overlaps_cell(ncell) }
      # if overlap_cells.empty?
      #   puts "no source cell for time #{time}"
      #   next
      # end
      next if overlap_cells.empty? # no source cell

      # Map each to their intersecting region and find the one with the largest duration.
      sorted_by_intersection =  overlap_cells.sort do |x, y|
        r1 = x.overlapping_region(ncell)
        d1 = r1.last - r1.first

        r2 = y.overlapping_region(ncell)
        d2 = r2.last - r2.first

        d2 <=> d1 # largest first
      end
      winner = sorted_by_intersection.first

      ncell.arglist.each do |code|
        ncell.change_code(code, winner.get_code(code))
      end
      # p ncol.cells.size
    end
    return ncol
  end
end

#db_varObject

Note:

Not intended for general use. Modify at own risk.

Returns Java object for this column

Returns:

  • Java object for this column



332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
# File 'datavyu_api.rb', line 332

class RColumn

  attr_accessor :name, :type, :cells, :arglist, :old_args, :dirty, :db_var, :hidden

  def initialize()
    self.hidden = false
  end

  # Validate code name. Replace non-alphanumeric characters
  # with underscores and prepend an underscore if the code
  # starts with a number.
  # @param name string to validate
  # @return [String] validated code name
  # @since 1.3.6
  def self.sanitize_codename(name)
    sanitized = name.gsub(/(\W)+/, '').downcase
    sanitized.gsub!(/(^\d{1})/, '_\\1')
    sanitized
  end

  def convert_argname(arg)
    RColumn.sanitize_codename(arg)
  end

  # @note This function is not for general use.
  # Creates the cell object in the Variable object.
  # @param newcells (required): Array of cells coming from the database via get_column
  # @param arglist (required): Array of the names of the arguments from the database
  def set_cells(newcells, arglist)
    print_debug "Setting cells"
    @cells = Array.new
    @arglist = Array.new
    arglist.each do |arg|
      # Regex to delete any character not a-z,0-9,or _
      print_debug arg
      @arglist << RColumn.sanitize_codename(arg)
    end
    if !newcells.nil?
      ord = 0
      newcells.each do |cell|
        ord += 1
        c = RCell.new
        c.onset = cell.getOnset
        c.offset = cell.getOffset
        c.db_cell = cell
        c.parent = @name
        vals = Array.new
        if cell.getVariable.getRootNode.type == Argument::Type::MATRIX
          for val in cell.getCellValue().getArguments
            vals << val.toString
          end
        else
          vals << cell.getCellValue().toString
        end
        c.set_args(vals, @arglist)
        c.ordinal = ord
        @cells << c
      end
    end
  end

  # Creates a new, blank cell at the end of this variable's cell array.
  # If a template cell is provided, copies over onset and offset times and code values for any matching code names.
  # @param cell [RCell] template cell
  # @return [RCell] Reference to the cell that was just created.  Modify the cell using this reference.
  # @example
  #   trial = get_column("trial")
  #   new_cell = trial.new_cell()
  #   new_cell.onset = 1000
  #   set_column(trial)
  def new_cell(cell = nil)
    c = RCell.new
    c.set_args('', @arglist)
    if(cell.nil?)
      c.onset = 0
      c.offset = 0
      c.ordinal = 0
    else
      c.onset = cell.onset
      c.offset = cell.offset
      self.arglist.each do |code|
        c.change_code(code, cell.get_arg(code)) if cell.arglist.include?(code)
      end
    end
    c.parent = @name
    @cells << c
    return c
  end
  alias :make_new_cell :new_cell
  alias :create_cell :new_cell

  # Sorts cells and saves column's cells by ascending onset times.
  # @return nil
  def sort_cells()
    cells.sort! { |a, b| a.onset <=> b.onset }
  end

  # Changes the name of a code. Updates the name for all cells in the column
  # @param old_name the name of the argument you want to change
  # @param new_name the name you want to change old_name to
  # @return nil
  def change_code_name(old_name, new_name)
    i = @old_args.index(old_name)
    @old_args[i] = new_name

    # Sanitize code
    old_name = RColumn.sanitize_codename(old_name)

    i = @arglist.index(old_name)
    @arglist[i] = new_name
    for cell in @cells
      cell.change_code_name(i, new_name)
    end

    @dirty = true
  end
  alias :change_arg_name :change_code_name

  # Add a code to this column. Updates all cells in column with new code.
  # @param [String] name the name of the new code
  # @return nil
  def add_code(name)
    @old_args << name
    san_name = RColumn.sanitize_codename(name)

    @arglist << san_name
    for cell in @cells
      cell.add_arg(san_name)
    end

    @dirty = true
  end
  alias :add_arg :add_code

  # Remove a code from this column. Updates all cells in column.
  # @param [String] name the name of the code to remove
  # @return nil
  def remove_code(name)
    @old_args.delete(name)

    san_name = RColumn.sanitize_codename(name)
    @arglist.delete(san_name)

    for cell in @cells
      cell.remove_arg(san_name)
    end

    @dirty = true
  end
  alias :remove_arg :remove_code

  # Set hidden state of this column
  # @param value [true, false] true to hide column in spreadsheet, false to show
  # @return nil
  def set_hidden(value)
    @hidden = value
  end

  # Resamples the cells of this column using given step size.
  # Optionally can specify the start and end time-points.
  # @param [Integer] step step size to resample with, in milliseconds
  # @param [Hash] opts options
  # @option opts [String] :column_name (self.name) name of returned column
  # @option opts [Integer] :start_time (earliest onset) time to start resampling from, in milliseconds
  # @option opts [Integer] :stop_time (latest offset) time to stop resampling at, in milliseconds
  # @return [RColumn] new column with resampled cells
  # @note Undefined behavior for columns whose cells overlap with each other.
  # @since 1.3.6
  def resample(step, opts={})
    @resample_defaults = {
      :column_name => self.name,
      :start_time => :earliest,
      :stop_time => :latest
    }

    opts = @resample_defaults.merge(opts)
    if opts[:start_time] == :earliest
      opts[:start_time] = @cells.map(&:onset).min
    end
    if opts[:stop_time] == :latest
      opts[:stop_time] = @cells.map(&:offset).max
    end

    # Construct new column
    ncol = new_column(opts[:column_name], self.arglist)
    # Construct new cells spanning range.
    ( (opts[:start_time])..(opts[:stop_time]) ).step(step) do |time|
      ncell = ncol.new_cell
      ncell.onset = time
      ncell.offset = time + step - 1

      # Find overlapping cells from self in this time region
      overlap_cells = self.cells.select{ |x| x.overlaps_cell(ncell) }
      # if overlap_cells.empty?
      #   puts "no source cell for time #{time}"
      #   next
      # end
      next if overlap_cells.empty? # no source cell

      # Map each to their intersecting region and find the one with the largest duration.
      sorted_by_intersection =  overlap_cells.sort do |x, y|
        r1 = x.overlapping_region(ncell)
        d1 = r1.last - r1.first

        r2 = y.overlapping_region(ncell)
        d2 = r2.last - r2.first

        d2 <=> d1 # largest first
      end
      winner = sorted_by_intersection.first

      ncell.arglist.each do |code|
        ncell.change_code(code, winner.get_code(code))
      end
      # p ncol.cells.size
    end
    return ncol
  end
end

#dirtyObject

Returns the value of attribute dirty



334
335
336
# File 'datavyu_api.rb', line 334

def dirty
  @dirty
end

#hiddentrue, false

Returns visibility of column in spreadsheet

Returns:

  • (true, false)

    visibility of column in spreadsheet



332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
# File 'datavyu_api.rb', line 332

class RColumn

  attr_accessor :name, :type, :cells, :arglist, :old_args, :dirty, :db_var, :hidden

  def initialize()
    self.hidden = false
  end

  # Validate code name. Replace non-alphanumeric characters
  # with underscores and prepend an underscore if the code
  # starts with a number.
  # @param name string to validate
  # @return [String] validated code name
  # @since 1.3.6
  def self.sanitize_codename(name)
    sanitized = name.gsub(/(\W)+/, '').downcase
    sanitized.gsub!(/(^\d{1})/, '_\\1')
    sanitized
  end

  def convert_argname(arg)
    RColumn.sanitize_codename(arg)
  end

  # @note This function is not for general use.
  # Creates the cell object in the Variable object.
  # @param newcells (required): Array of cells coming from the database via get_column
  # @param arglist (required): Array of the names of the arguments from the database
  def set_cells(newcells, arglist)
    print_debug "Setting cells"
    @cells = Array.new
    @arglist = Array.new
    arglist.each do |arg|
      # Regex to delete any character not a-z,0-9,or _
      print_debug arg
      @arglist << RColumn.sanitize_codename(arg)
    end
    if !newcells.nil?
      ord = 0
      newcells.each do |cell|
        ord += 1
        c = RCell.new
        c.onset = cell.getOnset
        c.offset = cell.getOffset
        c.db_cell = cell
        c.parent = @name
        vals = Array.new
        if cell.getVariable.getRootNode.type == Argument::Type::MATRIX
          for val in cell.getCellValue().getArguments
            vals << val.toString
          end
        else
          vals << cell.getCellValue().toString
        end
        c.set_args(vals, @arglist)
        c.ordinal = ord
        @cells << c
      end
    end
  end

  # Creates a new, blank cell at the end of this variable's cell array.
  # If a template cell is provided, copies over onset and offset times and code values for any matching code names.
  # @param cell [RCell] template cell
  # @return [RCell] Reference to the cell that was just created.  Modify the cell using this reference.
  # @example
  #   trial = get_column("trial")
  #   new_cell = trial.new_cell()
  #   new_cell.onset = 1000
  #   set_column(trial)
  def new_cell(cell = nil)
    c = RCell.new
    c.set_args('', @arglist)
    if(cell.nil?)
      c.onset = 0
      c.offset = 0
      c.ordinal = 0
    else
      c.onset = cell.onset
      c.offset = cell.offset
      self.arglist.each do |code|
        c.change_code(code, cell.get_arg(code)) if cell.arglist.include?(code)
      end
    end
    c.parent = @name
    @cells << c
    return c
  end
  alias :make_new_cell :new_cell
  alias :create_cell :new_cell

  # Sorts cells and saves column's cells by ascending onset times.
  # @return nil
  def sort_cells()
    cells.sort! { |a, b| a.onset <=> b.onset }
  end

  # Changes the name of a code. Updates the name for all cells in the column
  # @param old_name the name of the argument you want to change
  # @param new_name the name you want to change old_name to
  # @return nil
  def change_code_name(old_name, new_name)
    i = @old_args.index(old_name)
    @old_args[i] = new_name

    # Sanitize code
    old_name = RColumn.sanitize_codename(old_name)

    i = @arglist.index(old_name)
    @arglist[i] = new_name
    for cell in @cells
      cell.change_code_name(i, new_name)
    end

    @dirty = true
  end
  alias :change_arg_name :change_code_name

  # Add a code to this column. Updates all cells in column with new code.
  # @param [String] name the name of the new code
  # @return nil
  def add_code(name)
    @old_args << name
    san_name = RColumn.sanitize_codename(name)

    @arglist << san_name
    for cell in @cells
      cell.add_arg(san_name)
    end

    @dirty = true
  end
  alias :add_arg :add_code

  # Remove a code from this column. Updates all cells in column.
  # @param [String] name the name of the code to remove
  # @return nil
  def remove_code(name)
    @old_args.delete(name)

    san_name = RColumn.sanitize_codename(name)
    @arglist.delete(san_name)

    for cell in @cells
      cell.remove_arg(san_name)
    end

    @dirty = true
  end
  alias :remove_arg :remove_code

  # Set hidden state of this column
  # @param value [true, false] true to hide column in spreadsheet, false to show
  # @return nil
  def set_hidden(value)
    @hidden = value
  end

  # Resamples the cells of this column using given step size.
  # Optionally can specify the start and end time-points.
  # @param [Integer] step step size to resample with, in milliseconds
  # @param [Hash] opts options
  # @option opts [String] :column_name (self.name) name of returned column
  # @option opts [Integer] :start_time (earliest onset) time to start resampling from, in milliseconds
  # @option opts [Integer] :stop_time (latest offset) time to stop resampling at, in milliseconds
  # @return [RColumn] new column with resampled cells
  # @note Undefined behavior for columns whose cells overlap with each other.
  # @since 1.3.6
  def resample(step, opts={})
    @resample_defaults = {
      :column_name => self.name,
      :start_time => :earliest,
      :stop_time => :latest
    }

    opts = @resample_defaults.merge(opts)
    if opts[:start_time] == :earliest
      opts[:start_time] = @cells.map(&:onset).min
    end
    if opts[:stop_time] == :latest
      opts[:stop_time] = @cells.map(&:offset).max
    end

    # Construct new column
    ncol = new_column(opts[:column_name], self.arglist)
    # Construct new cells spanning range.
    ( (opts[:start_time])..(opts[:stop_time]) ).step(step) do |time|
      ncell = ncol.new_cell
      ncell.onset = time
      ncell.offset = time + step - 1

      # Find overlapping cells from self in this time region
      overlap_cells = self.cells.select{ |x| x.overlaps_cell(ncell) }
      # if overlap_cells.empty?
      #   puts "no source cell for time #{time}"
      #   next
      # end
      next if overlap_cells.empty? # no source cell

      # Map each to their intersecting region and find the one with the largest duration.
      sorted_by_intersection =  overlap_cells.sort do |x, y|
        r1 = x.overlapping_region(ncell)
        d1 = r1.last - r1.first

        r2 = y.overlapping_region(ncell)
        d2 = r2.last - r2.first

        d2 <=> d1 # largest first
      end
      winner = sorted_by_intersection.first

      ncell.arglist.each do |code|
        ncell.change_code(code, winner.get_code(code))
      end
      # p ncol.cells.size
    end
    return ncol
  end
end

#nameString

Returns name of the column

Returns:

  • (String)

    name of the column



332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
# File 'datavyu_api.rb', line 332

class RColumn

  attr_accessor :name, :type, :cells, :arglist, :old_args, :dirty, :db_var, :hidden

  def initialize()
    self.hidden = false
  end

  # Validate code name. Replace non-alphanumeric characters
  # with underscores and prepend an underscore if the code
  # starts with a number.
  # @param name string to validate
  # @return [String] validated code name
  # @since 1.3.6
  def self.sanitize_codename(name)
    sanitized = name.gsub(/(\W)+/, '').downcase
    sanitized.gsub!(/(^\d{1})/, '_\\1')
    sanitized
  end

  def convert_argname(arg)
    RColumn.sanitize_codename(arg)
  end

  # @note This function is not for general use.
  # Creates the cell object in the Variable object.
  # @param newcells (required): Array of cells coming from the database via get_column
  # @param arglist (required): Array of the names of the arguments from the database
  def set_cells(newcells, arglist)
    print_debug "Setting cells"
    @cells = Array.new
    @arglist = Array.new
    arglist.each do |arg|
      # Regex to delete any character not a-z,0-9,or _
      print_debug arg
      @arglist << RColumn.sanitize_codename(arg)
    end
    if !newcells.nil?
      ord = 0
      newcells.each do |cell|
        ord += 1
        c = RCell.new
        c.onset = cell.getOnset
        c.offset = cell.getOffset
        c.db_cell = cell
        c.parent = @name
        vals = Array.new
        if cell.getVariable.getRootNode.type == Argument::Type::MATRIX
          for val in cell.getCellValue().getArguments
            vals << val.toString
          end
        else
          vals << cell.getCellValue().toString
        end
        c.set_args(vals, @arglist)
        c.ordinal = ord
        @cells << c
      end
    end
  end

  # Creates a new, blank cell at the end of this variable's cell array.
  # If a template cell is provided, copies over onset and offset times and code values for any matching code names.
  # @param cell [RCell] template cell
  # @return [RCell] Reference to the cell that was just created.  Modify the cell using this reference.
  # @example
  #   trial = get_column("trial")
  #   new_cell = trial.new_cell()
  #   new_cell.onset = 1000
  #   set_column(trial)
  def new_cell(cell = nil)
    c = RCell.new
    c.set_args('', @arglist)
    if(cell.nil?)
      c.onset = 0
      c.offset = 0
      c.ordinal = 0
    else
      c.onset = cell.onset
      c.offset = cell.offset
      self.arglist.each do |code|
        c.change_code(code, cell.get_arg(code)) if cell.arglist.include?(code)
      end
    end
    c.parent = @name
    @cells << c
    return c
  end
  alias :make_new_cell :new_cell
  alias :create_cell :new_cell

  # Sorts cells and saves column's cells by ascending onset times.
  # @return nil
  def sort_cells()
    cells.sort! { |a, b| a.onset <=> b.onset }
  end

  # Changes the name of a code. Updates the name for all cells in the column
  # @param old_name the name of the argument you want to change
  # @param new_name the name you want to change old_name to
  # @return nil
  def change_code_name(old_name, new_name)
    i = @old_args.index(old_name)
    @old_args[i] = new_name

    # Sanitize code
    old_name = RColumn.sanitize_codename(old_name)

    i = @arglist.index(old_name)
    @arglist[i] = new_name
    for cell in @cells
      cell.change_code_name(i, new_name)
    end

    @dirty = true
  end
  alias :change_arg_name :change_code_name

  # Add a code to this column. Updates all cells in column with new code.
  # @param [String] name the name of the new code
  # @return nil
  def add_code(name)
    @old_args << name
    san_name = RColumn.sanitize_codename(name)

    @arglist << san_name
    for cell in @cells
      cell.add_arg(san_name)
    end

    @dirty = true
  end
  alias :add_arg :add_code

  # Remove a code from this column. Updates all cells in column.
  # @param [String] name the name of the code to remove
  # @return nil
  def remove_code(name)
    @old_args.delete(name)

    san_name = RColumn.sanitize_codename(name)
    @arglist.delete(san_name)

    for cell in @cells
      cell.remove_arg(san_name)
    end

    @dirty = true
  end
  alias :remove_arg :remove_code

  # Set hidden state of this column
  # @param value [true, false] true to hide column in spreadsheet, false to show
  # @return nil
  def set_hidden(value)
    @hidden = value
  end

  # Resamples the cells of this column using given step size.
  # Optionally can specify the start and end time-points.
  # @param [Integer] step step size to resample with, in milliseconds
  # @param [Hash] opts options
  # @option opts [String] :column_name (self.name) name of returned column
  # @option opts [Integer] :start_time (earliest onset) time to start resampling from, in milliseconds
  # @option opts [Integer] :stop_time (latest offset) time to stop resampling at, in milliseconds
  # @return [RColumn] new column with resampled cells
  # @note Undefined behavior for columns whose cells overlap with each other.
  # @since 1.3.6
  def resample(step, opts={})
    @resample_defaults = {
      :column_name => self.name,
      :start_time => :earliest,
      :stop_time => :latest
    }

    opts = @resample_defaults.merge(opts)
    if opts[:start_time] == :earliest
      opts[:start_time] = @cells.map(&:onset).min
    end
    if opts[:stop_time] == :latest
      opts[:stop_time] = @cells.map(&:offset).max
    end

    # Construct new column
    ncol = new_column(opts[:column_name], self.arglist)
    # Construct new cells spanning range.
    ( (opts[:start_time])..(opts[:stop_time]) ).step(step) do |time|
      ncell = ncol.new_cell
      ncell.onset = time
      ncell.offset = time + step - 1

      # Find overlapping cells from self in this time region
      overlap_cells = self.cells.select{ |x| x.overlaps_cell(ncell) }
      # if overlap_cells.empty?
      #   puts "no source cell for time #{time}"
      #   next
      # end
      next if overlap_cells.empty? # no source cell

      # Map each to their intersecting region and find the one with the largest duration.
      sorted_by_intersection =  overlap_cells.sort do |x, y|
        r1 = x.overlapping_region(ncell)
        d1 = r1.last - r1.first

        r2 = y.overlapping_region(ncell)
        d2 = r2.last - r2.first

        d2 <=> d1 # largest first
      end
      winner = sorted_by_intersection.first

      ncell.arglist.each do |code|
        ncell.change_code(code, winner.get_code(code))
      end
      # p ncol.cells.size
    end
    return ncol
  end
end

#old_argsObject

Returns the value of attribute old_args



334
335
336
# File 'datavyu_api.rb', line 334

def old_args
  @old_args
end

#typeObject

Returns the value of attribute type



334
335
336
# File 'datavyu_api.rb', line 334

def type
  @type
end

Class Method Details

.sanitize_codename(name) ⇒ String

Validate code name. Replace non-alphanumeric characters with underscores and prepend an underscore if the code starts with a number.

Parameters:

  • name

    string to validate

Returns:

  • (String)

    validated code name

Since:

  • 1.3.6



346
347
348
349
350
# File 'datavyu_api.rb', line 346

def self.sanitize_codename(name)
  sanitized = name.gsub(/(\W)+/, '').downcase
  sanitized.gsub!(/(^\d{1})/, '_\\1')
  sanitized
end

Instance Method Details

#add_code(name) ⇒ Object Also known as: add_arg

Add a code to this column. Updates all cells in column with new code.

Parameters:

  • name (String)

    the name of the new code

Returns:

  • nil



453
454
455
456
457
458
459
460
461
462
463
# File 'datavyu_api.rb', line 453

def add_code(name)
  @old_args << name
  san_name = RColumn.sanitize_codename(name)

  @arglist << san_name
  for cell in @cells
    cell.add_arg(san_name)
  end

  @dirty = true
end

#change_code_name(old_name, new_name) ⇒ Object Also known as: change_arg_name

Changes the name of a code. Updates the name for all cells in the column

Parameters:

  • old_name

    the name of the argument you want to change

  • new_name

    the name you want to change old_name to

Returns:

  • nil



433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
# File 'datavyu_api.rb', line 433

def change_code_name(old_name, new_name)
  i = @old_args.index(old_name)
  @old_args[i] = new_name

  # Sanitize code
  old_name = RColumn.sanitize_codename(old_name)

  i = @arglist.index(old_name)
  @arglist[i] = new_name
  for cell in @cells
    cell.change_code_name(i, new_name)
  end

  @dirty = true
end

#convert_argname(arg) ⇒ Object



352
353
354
# File 'datavyu_api.rb', line 352

def convert_argname(arg)
  RColumn.sanitize_codename(arg)
end

#new_cell(cell = nil) ⇒ RCell Also known as: make_new_cell, create_cell

Creates a new, blank cell at the end of this variable's cell array. If a template cell is provided, copies over onset and offset times and code values for any matching code names.

Examples:

trial = get_column("trial")
new_cell = trial.new_cell()
new_cell.onset = 1000
set_column(trial)

Parameters:

  • cell (RCell) (defaults to: nil)

    template cell

Returns:

  • (RCell)

    Reference to the cell that was just created. Modify the cell using this reference.



402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
# File 'datavyu_api.rb', line 402

def new_cell(cell = nil)
  c = RCell.new
  c.set_args('', @arglist)
  if(cell.nil?)
    c.onset = 0
    c.offset = 0
    c.ordinal = 0
  else
    c.onset = cell.onset
    c.offset = cell.offset
    self.arglist.each do |code|
      c.change_code(code, cell.get_arg(code)) if cell.arglist.include?(code)
    end
  end
  c.parent = @name
  @cells << c
  return c
end

#remove_code(name) ⇒ Object Also known as: remove_arg

Remove a code from this column. Updates all cells in column.

Parameters:

  • name (String)

    the name of the code to remove

Returns:

  • nil



469
470
471
472
473
474
475
476
477
478
479
480
# File 'datavyu_api.rb', line 469

def remove_code(name)
  @old_args.delete(name)

  san_name = RColumn.sanitize_codename(name)
  @arglist.delete(san_name)

  for cell in @cells
    cell.remove_arg(san_name)
  end

  @dirty = true
end

#resample(step, opts = {}) ⇒ RColumn

Note:

Undefined behavior for columns whose cells overlap with each other.

Resamples the cells of this column using given step size. Optionally can specify the start and end time-points.

Parameters:

  • step (Integer)

    step size to resample with, in milliseconds

  • opts (Hash) (defaults to: {})

    options

Options Hash (opts):

  • :column_name (String) — default: self.name

    name of returned column

  • :start_time (Integer) — default: earliest onset

    time to start resampling from, in milliseconds

  • :stop_time (Integer) — default: latest offset

    time to stop resampling at, in milliseconds

Returns:

  • (RColumn)

    new column with resampled cells

Since:

  • 1.3.6



500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
# File 'datavyu_api.rb', line 500

def resample(step, opts={})
  @resample_defaults = {
    :column_name => self.name,
    :start_time => :earliest,
    :stop_time => :latest
  }

  opts = @resample_defaults.merge(opts)
  if opts[:start_time] == :earliest
    opts[:start_time] = @cells.map(&:onset).min
  end
  if opts[:stop_time] == :latest
    opts[:stop_time] = @cells.map(&:offset).max
  end

  # Construct new column
  ncol = new_column(opts[:column_name], self.arglist)
  # Construct new cells spanning range.
  ( (opts[:start_time])..(opts[:stop_time]) ).step(step) do |time|
    ncell = ncol.new_cell
    ncell.onset = time
    ncell.offset = time + step - 1

    # Find overlapping cells from self in this time region
    overlap_cells = self.cells.select{ |x| x.overlaps_cell(ncell) }
    # if overlap_cells.empty?
    #   puts "no source cell for time #{time}"
    #   next
    # end
    next if overlap_cells.empty? # no source cell

    # Map each to their intersecting region and find the one with the largest duration.
    sorted_by_intersection =  overlap_cells.sort do |x, y|
      r1 = x.overlapping_region(ncell)
      d1 = r1.last - r1.first

      r2 = y.overlapping_region(ncell)
      d2 = r2.last - r2.first

      d2 <=> d1 # largest first
    end
    winner = sorted_by_intersection.first

    ncell.arglist.each do |code|
      ncell.change_code(code, winner.get_code(code))
    end
    # p ncol.cells.size
  end
  return ncol
end

#set_cells(newcells, arglist) ⇒ Object

Note:

This function is not for general use.

Creates the cell object in the Variable object.

Parameters:

  • newcells (required)

    : Array of cells coming from the database via get_column

  • arglist (required)

    : Array of the names of the arguments from the database



360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
# File 'datavyu_api.rb', line 360

def set_cells(newcells, arglist)
  print_debug "Setting cells"
  @cells = Array.new
  @arglist = Array.new
  arglist.each do |arg|
    # Regex to delete any character not a-z,0-9,or _
    print_debug arg
    @arglist << RColumn.sanitize_codename(arg)
  end
  if !newcells.nil?
    ord = 0
    newcells.each do |cell|
      ord += 1
      c = RCell.new
      c.onset = cell.getOnset
      c.offset = cell.getOffset
      c.db_cell = cell
      c.parent = @name
      vals = Array.new
      if cell.getVariable.getRootNode.type == Argument::Type::MATRIX
        for val in cell.getCellValue().getArguments
          vals << val.toString
        end
      else
        vals << cell.getCellValue().toString
      end
      c.set_args(vals, @arglist)
      c.ordinal = ord
      @cells << c
    end
  end
end

#set_hidden(value) ⇒ Object

Set hidden state of this column

Parameters:

  • value (true, false)

    true to hide column in spreadsheet, false to show

Returns:

  • nil



486
487
488
# File 'datavyu_api.rb', line 486

def set_hidden(value)
  @hidden = value
end

#sort_cellsObject

Sorts cells and saves column's cells by ascending onset times.

Returns:

  • nil



425
426
427
# File 'datavyu_api.rb', line 425

def sort_cells()
  cells.sort! { |a, b| a.onset <=> b.onset }
end