Advertisement
Guest User

Check Reliability Script

a guest
Jul 10th, 2013
163
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 59.75 KB | None | 0 0
  1. #-------------------------------------------------------------------
  2. # OpenSHAPA API v 0.984
  3.  
  4. # Please read the function headers for information on how to use them.
  5.  
  6. # CHANGE LOG
  7. # 0.984 2/16/11 - Fixed a heap error bug in mutex, several bugs with editing
  8. # variable arguments. Added functions for adding variable
  9. # arguments, and framework for generic print script. Several
  10. # versions of incremental fixes.
  11. # 0.98 10/10/10 - Added function to get list of columns, fixed up the import
  12. # Macshapa function. It should work for most files now.
  13. # 0.97 8/11/10 - Added a function to check for valid codes in a variable,
  14. # and fixed a bug with check_rel.
  15. # 0.96 8/11/10 - Added a function to check reliability between two columns
  16. # and print either to a file or to the console.
  17. # 0.95 7/22/10 - Added a function to transfer columns between files and
  18. # added headers to functions that didn't have any.
  19. # 0.94 7/22/10 - Fixed the save_db function so it works with opf files
  20. # and will detect if you are saving a csv file.
  21. # 0.93 7/20/10 - Merged in function to read MacSHAPA Closed database
  22. # files into OpenSHAPA.
  23. # 0.92 6/29/10 - Added function to delete columns
  24. # 0.91 6/25/10 - Added load functions, fixed some issues with Mutex
  25. # => save still has some issues though; working out how to
  26. # => access the project variables from Ruby.
  27.  
  28. # Licensing information:
  29. #
  30. # Permission is hereby granted, free of charge, to any person obtaining a copy
  31. # of this software and associated documentation files (the "Software"), to deal
  32. # in the Software without restriction, including without limitation the rights
  33. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  34. # copies of the Software, and to permit persons to whom the Software is
  35. # furnished to do so, subject to the following conditions:
  36. #
  37. # The above copyright notice and this permission notice shall be included in
  38. # all copies or substantial portions of the Software.
  39. #
  40. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  41. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  42. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  43. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  44. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  45. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  46. # THE SOFTWARE.
  47. #-------------------------------------------------------------------
  48.  
  49. require 'java'
  50. require 'csv'
  51. require 'time'
  52. require 'date'
  53. #require 'ftools'
  54.  
  55. import 'org.openshapa.models.db.legacy.Database'
  56. import 'org.openshapa.models.db.legacy.DataColumn'
  57. import 'org.openshapa.models.db.legacy.MacshapaDatabase'
  58. import 'org.openshapa.models.db.legacy.MatrixVocabElement'
  59. import 'org.openshapa.models.db.legacy.Matrix'
  60. import 'org.openshapa.models.db.legacy.FloatDataValue'
  61. import 'org.openshapa.models.db.legacy.IntDataValue'
  62. import 'org.openshapa.models.db.legacy.TextStringDataValue'
  63. import 'org.openshapa.models.db.legacy.QuoteStringDataValue'
  64. import 'org.openshapa.models.db.legacy.UndefinedDataValue'
  65. import 'org.openshapa.models.db.legacy.NominalDataValue'
  66. import 'org.openshapa.models.db.legacy.PredDataValue'
  67. import 'org.openshapa.models.db.legacy.Predicate'
  68. import 'org.openshapa.models.db.legacy.PredicateVocabElement'
  69. import 'org.openshapa.models.db.legacy.FloatFormalArg'
  70. import 'org.openshapa.models.db.legacy.IntFormalArg'
  71. import 'org.openshapa.models.db.legacy.NominalFormalArg'
  72. import 'org.openshapa.models.db.legacy.PredFormalArg'
  73. import 'org.openshapa.models.db.legacy.QuoteStringFormalArg'
  74. import 'org.openshapa.models.db.legacy.UnTypedFormalArg'
  75. import 'org.openshapa.models.db.legacy.DBElement'
  76. import 'org.openshapa.models.db.legacy.TimeStamp'
  77. import 'org.openshapa.models.db.legacy.DataCell'
  78. import 'org.openshapa.models.db.legacy.SystemErrorException'
  79. import 'org.openshapa.models.project.Project'
  80. import 'org.openshapa.controllers.SaveC'
  81. import 'org.openshapa.controllers.OpenC'
  82. import 'org.openshapa.controllers.project.ProjectController'
  83. include_class(['java.lang.Object', 'java.awt.event.ActionListener', 'javax.swing.JFrame','javax.swing.JLabel','javax.swing.JComboBox','javax.swing.JButton','javax.swing.JPanel','javax.swing.JTable','javax.swing.JTextField', 'java.awt.GridBagLayout', 'java.awt.GridBagConstraints'])
  84.  
  85. class Cell
  86.  
  87. attr_accessor :ordinal, :onset, :offset, :arglist, :argvals
  88.  
  89.  
  90. #-------------------------------------------------------------------
  91. # Note: This method is not for general use, it is used only when creating
  92. # this variable from the database in the getVariable method.
  93. #
  94. # Method name: set_args
  95. # Function: sets up methods that can be used to reference the arguments in
  96. # the cell.
  97. # Arguments:
  98. # => argvals (required): Values of the arguments being created
  99. # => arglist (required): Names of the arguments being created
  100. #-------------------------------------------------------------------
  101.  
  102. def set_args(argvals, arglist)
  103. @arglist = arglist
  104. @argvals = argvals
  105. i = 0
  106. if argvals == ""
  107. @argvals = Array.new
  108. arglist.each do |arg|
  109. @argvals << nil
  110. end
  111. end
  112. arglist.each do |arg|
  113.  
  114. if @argvals[i].nil?
  115. @argvals[i] = ""
  116. end
  117. #Tricky magic part where we are defining var names on the fly. Escaped quotes turn everything to strings.
  118. #Handle this later by allowing numbers to be numbers but keeping strings.
  119.  
  120. instance_eval "def #{arg}; return argvals[#{i}]; end"
  121. i += 1
  122. end
  123. end
  124.  
  125.  
  126. def change_arg_name(i, new_name)
  127. instance_eval "def #{new_name}; return argvals[#{i}]; end"
  128. end
  129.  
  130. #-------------------------------------------------------------------
  131. # Method name: change_arg
  132. # Function: Changes the value of an argument in a cell.
  133. # Arguments:
  134. # => arg (required): Name of the argument to be changed
  135. # => val (required): Value to change the argument to
  136. # Returns:
  137. # => None
  138. # Usage:
  139. # trial = getVariable("trial")
  140. # trial.cells[0].change_arg("onset", 1000)
  141. # setVariable("trial",trial)
  142. #-------------------------------------------------------------------
  143.  
  144. def change_arg(arg, val)
  145. if arg == "onset"
  146. @onset = val
  147. elsif arg == "offset"
  148. @offset = val
  149. elsif arg == "ordinal"
  150. @ordinal = val
  151. else
  152. for i in 0..arglist.length-1
  153. if arglist[i] == arg and not arg.nil?
  154. argvals[i] = val.to_s
  155. end
  156. end
  157. end
  158. end
  159.  
  160. #-------------------------------------------------------------------
  161. # Method name: print_all
  162. # Function: Dumps all of the arguments in the cell to a string.
  163. # Arguments:
  164. # => p (optional): The seperator used between the arguments. Defaults to tab (\t)
  165. # Returns:
  166. # => A string of the arguments starting with ordinal/onset/offset then argument.
  167. # Usage:
  168. # trial = getVariable("trial")
  169. # print trial.cells[0].print_all()
  170. #-------------------------------------------------------------------
  171.  
  172. def print_all(*p)
  173. if p.empty?
  174. p << "\t"
  175. end
  176. print @ordinal.to_s + p[0] + @onset.to_s + p[0] + @offset.to_s + p[0]
  177. @arglist.each do |arg|
  178. t = eval "self.#{arg}"
  179. if t == nil
  180. v = ""
  181. else
  182. v = t
  183. end
  184. print v + p[0]
  185. end
  186. end
  187. end
  188.  
  189. #-------------------------------------------------------------------
  190. # Class name: Variable
  191. # Function: This is the Ruby container for OpenSHAPA variables.
  192. #-------------------------------------------------------------------
  193.  
  194. class Variable
  195.  
  196. attr_accessor :name, :type, :cells, :arglist, :old_args
  197.  
  198. #-------------------------------------------------------------------
  199. # NOTE: This function is not for general use.
  200. #
  201. # Method name: set_cells
  202. # Function: Creates the cell object in the Variable object.
  203. # Arguments:
  204. # => newcells (required): Array of cells coming from the database via getVariable
  205. # => arglist (required): Array of the names of the arguments from the database
  206. #-------------------------------------------------------------------
  207.  
  208. def set_cells(newcells, arglist)
  209. @cells = Array.new
  210. @arglist = Array.new
  211. arglist.each do |arg|
  212. # Regex to delete any character not a-z,0-9,or _
  213. if ["0","1","2","3","4","5","6","7","8","9"].include?(arg[1].chr)
  214. arg = "_" + arg
  215. end
  216. @arglist << arg.gsub(/(\W)+/,"").downcase
  217. end
  218. if !newcells.nil?
  219. newcells.each do |cell|
  220. c = Cell.new
  221. c.onset = cell[0]
  222. c.offset = cell[1]
  223. c.set_args(cell[2],@arglist)
  224. c.ordinal = cell[3]
  225. @cells << c
  226. end
  227. end
  228. end
  229.  
  230. #-------------------------------------------------------------------
  231. # Method name: make_new_cell
  232. # Function: Creates a new, blank cell at the end of this variable's cell array
  233. # Arguments:
  234. # => None
  235. # Returns:
  236. # => Reference to the cell that was just created. Modify the cell using this reference.
  237. # Usage:
  238. # trial = getVariable("trial")
  239. # new_cell = trial.make_new_cell()
  240. # new_cell.change_arg("onset", 1000)
  241. # setVariable("trial", trial)
  242. #-------------------------------------------------------------------
  243. def make_new_cell()
  244. c = Cell.new
  245. c.onset = 0
  246. c.offset = 0
  247. c.ordinal = 0
  248. c.set_args("", @arglist)
  249. @cells << c
  250. return c
  251. end
  252.  
  253. def sort_cells()
  254. cells.sort! { |a,b| a.onset <=> b.onset }
  255. end
  256.  
  257.  
  258. #-------------------------------------------------------------------
  259. # Method name: change_arg_name
  260. # Function: Creates a new, blank cell at the end of this variable's cell array
  261. # Arguments:
  262. # => old_name: the name of the argument you want to change
  263. # => new_name: the name you want to change old_name to
  264. # Returns:
  265. # => nothing.
  266. # Usage:
  267. # trial = getVariable("trial")
  268. #
  269. #-------------------------------------------------------------------
  270. def change_arg_name(old_name, new_name)
  271. i = @old_args.index("<"+old_name+">")
  272. @old_args[i] = "<"+new_name+">"
  273. if ["0","1","2","3","4","5","6","7","8","9"].include?(old_name[1].chr)
  274. old_name = "_" + old_name
  275. end
  276. old_name = old_name.gsub(/(\W)+/,"").downcase
  277.  
  278. i = @arglist.index(old_name)
  279. @arglist[i] = new_name
  280. for cell in @cells
  281. cell.change_arg_name(i, new_name)
  282. end
  283.  
  284. end
  285. end
  286.  
  287. #-------------------------------------------------------------------
  288. # Method name: getVariable
  289. # Function: getVariable retrieves a variable from the database and puts it into a Ruby object.
  290. # Arguments:
  291. # => name (required): The OpenSHAPA name of the variable being retrieved
  292. # Returns:
  293. # => A Ruby object representation of the variable inside OpenSHAPA.
  294. # Usage:
  295. # trial = getVariable("trial")
  296. #-------------------------------------------------------------------
  297.  
  298. def getVariable(name)
  299. index = -1
  300.  
  301. # Find the internal database index of the column we are looking for.
  302. $db.get_col_order_vector.each do |col_index|
  303. if name == $db.get_data_column(col_index).get_name
  304. index = col_index
  305. end
  306. end
  307.  
  308. #puts "Got column index."
  309. #puts index
  310.  
  311.  
  312. dc = $db.get_data_column(index)
  313. mve = $db.get_matrix_ve(dc.get_its_mve_id)
  314.  
  315. # Convert each cell into an array and store in an array of arrays
  316. cells = Array.new
  317. arg_names = Array.new
  318.  
  319. if dc.get_its_mve_type == MatrixVocabElement::MatrixType::MATRIX
  320. for i in (0 .. (mve.get_num_formal_args - 1))
  321. fa = mve.get_formal_arg_copy(i)
  322. arg_names << fa.get_farg_name
  323. end
  324. end
  325.  
  326. for i in (1 .. dc.get_num_cells)
  327. cell = dc.get_db.get_cell(dc.get_id, i)
  328. c = Array.new
  329. c << cell.get_onset.get_time
  330. c << cell.get_offset.get_time
  331. c << cell.get_val.to_escaped_string.tr_s("(", "").tr_s(")", "").split(",")
  332. c << i
  333. cells << c
  334. end
  335.  
  336.  
  337. v = Variable.new
  338. v.name = name
  339. v.old_args = arg_names
  340. #v.type = dc.get_its_mve_type
  341. v.set_cells(cells, arg_names)
  342.  
  343.  
  344. return v
  345. end
  346.  
  347. #-------------------------------------------------------------------
  348. # Method name: setVariable
  349. # Function: setVariable will overwrite a variable in the database with the same name as the name argument.
  350. # If no variable with the same name exists, it will create a new variable.
  351. # Arguments:
  352. # => name (optional): The name of the variable being created
  353. # => var (required): The Ruby container of the variable to be put into the database. This is the return value of
  354. # createNewVariable or getVariable that has been modified.
  355. # Usage:
  356. # trial = getVariable("trial")
  357. # ** Do some modification to trial
  358. # setVariable("trial", trial)
  359. #-------------------------------------------------------------------
  360.  
  361. def setVariable(name, var)
  362.  
  363. # Since this code was already written for three separate values,
  364. # I'm just splitting it back up for now.
  365.  
  366. arg_names = var.old_args
  367. cells = Array.new
  368. var.cells.each do |cell|
  369. c = Array.new
  370. c << cell.onset
  371. c << cell.offset
  372. c << Array.new
  373. var.arglist.each do |arg|
  374. t = eval "cell.#{arg}"
  375. c[2] << t.to_s()
  376. end
  377. cells << c
  378. end
  379.  
  380. # If the column already exists, delete it and build a new one.
  381. # If it doesn't, just add a new one.
  382. if not $db.col_name_in_use(name)
  383. col = DataColumn.new($db, name, MatrixVocabElement::MatrixType::MATRIX)
  384. $db.add_column(col)
  385. else
  386. oldcol = $db.get_column(name)
  387. numcells = oldcol.get_num_cells
  388. numcells.downto(1) do |i|
  389. $db.remove_cell($db.get_cell(oldcol.get_id, i).get_id)
  390. end
  391. #$db.remove_column(oldcol.get_id)
  392.  
  393. #col = DataColumn.new($db, name, MatrixVocabElement::MatrixType::MATRIX)
  394. #$db.add_column(col)
  395. end
  396. # Check if matrix already defined
  397. col = $db.get_column(name)
  398. mve0 = $db.get_matrix_ve(col.its_mve_id)
  399. if mve0.get_num_formal_args() == 1
  400. # Setup structure of matrix column
  401. mve0 = MatrixVocabElement.new(mve0)
  402.  
  403. mve0.delete_formal_arg(0)
  404. arg_names.each do |arg|
  405. farg = NominalFormalArg.new($db, arg)
  406. mve0.append_formal_arg(farg)
  407. end
  408.  
  409. $db.replace_matrix_ve(mve0)
  410. end
  411. col = $db.get_column(name)
  412. mve0 = $db.get_matrix_ve(col.its_mve_id)
  413. matID0 = mve0.get_id()
  414. cells.each do |cell|
  415. #print "writing cell"
  416. c = DataCell.new($db, col.get_id, matID0)
  417. mat = Matrix.new($db, matID0)
  418.  
  419. if cell[0].to_i > 0
  420. c.onset = TimeStamp.new(1000, cell[0].to_i)
  421. end
  422. if cell[1].to_i > 0
  423. c.offset = TimeStamp.new(1000, cell[1].to_i)
  424. end
  425.  
  426. narg = 0
  427. cell[2].each do |dv|
  428. argid = mve0.get_formal_arg(narg).get_id()
  429. if dv == "" or dv == nil
  430. a = arg_names[narg]
  431. fdv = NominalDataValue.new($db, argid)
  432. fdv.clearValue()
  433. else
  434. fdv = NominalDataValue.new($db, argid, dv)
  435. end
  436.  
  437. mat.replaceArg(narg,fdv)
  438. narg += 1
  439. end
  440. c.set_val(mat)
  441. $db.append_cell(c)
  442. end
  443. end
  444.  
  445. #-------------------------------------------------------------------
  446. # Method name: make_rel
  447. # Function: This function will create a reliability column that is a copy
  448. # of another column in the database, copying every nth cell and
  449. # carrying over some of the arguments from the original, if wanted.
  450. # Arguments:
  451. # => relname (required): The name of the reliability column to be created.
  452. # => var_to_copy (required): The name of the variable in the database you
  453. # wish to copy.
  454. # => multiple_to_keep: The number of cells to skip. For every other cell, use 2.
  455. # => *args_to_keep: Comma separated strings for the arguments you want to keep
  456. # between cells. For example, "onset", "trialnum", "block" would keep
  457. # those three arguments in the new cells that are created.
  458. # Returns:
  459. # => A Ruby object representation of the rel column inside OpenSHAPA.
  460. # Usage:
  461. # rel_trial = make_rel("rel.trial", "trial", 2, "onset", "trialnum", "unit")
  462. #-------------------------------------------------------------------
  463.  
  464. def make_rel(relname, var_to_copy, multiple_to_keep, *args_to_keep)
  465. # Get the primary variable from the DB
  466. var_to_copy = getVariable(var_to_copy)
  467.  
  468. # Clip down cells to fit multiple to keep
  469. for i in 0..var_to_copy.cells.length-1
  470. if multiple_to_keep == 0
  471. var_to_copy.cells[i] = nil
  472. elsif var_to_copy.cells[i].ordinal % multiple_to_keep != 0
  473. var_to_copy.cells[i] = nil
  474. else
  475. var_to_copy.cells[i].ordinal = var_to_copy.cells[i].ordinal / multiple_to_keep
  476. end
  477. end
  478. # Clear out the nil cells
  479. var_to_copy.cells.compact!
  480.  
  481. var_to_copy.cells.each do |cell|
  482. if !args_to_keep.include?("onset")
  483. cell.onset = 0
  484. end
  485. if !args_to_keep.include?("offset")
  486. cell.offset = 0
  487. end
  488. cell.arglist.each do |arg|
  489. if !args_to_keep.include?(arg)
  490. cell.change_arg(arg,"")
  491. end
  492. end
  493. end
  494. setVariable(relname, var_to_copy)
  495. return var_to_copy
  496. end
  497.  
  498. #-------------------------------------------------------------------
  499. # Method name: createNewVariable
  500. # Function: Creates a brand new blank variable with argument *args and name name.
  501. # Arguments:
  502. # => name (required): The OpenSHAPA name of the variable being retrieved
  503. # => *args: (optional): List of arguments that the variable will contain. Onset, Offset, and
  504. # ordinal are created by default.
  505. # Returns:
  506. # => A Ruby object representation of the variable inside OpenSHAPA.
  507. # Usage:
  508. # trial = createNewVariable("trial", "trialnum", "unit")
  509. # blank_cell = trial.make_new_cell()
  510. # setVariable(trial)
  511. #-------------------------------------------------------------------
  512.  
  513. def createNewVariable(name, *args)
  514. v = Variable.new
  515.  
  516. v.name = name
  517.  
  518. if args[0].class == Array
  519. args = args[0]
  520. end
  521.  
  522. # Set the argument names in arg_names and set the database internal style with <argname> in old_args
  523. arg_names = Array.new
  524. old_args = Array.new
  525. for arg in args
  526. arg_names << arg
  527. old_args << "<" + arg.to_s + ">"
  528. end
  529. c = Array.new
  530. v.old_args = old_args
  531. v.set_cells(nil, arg_names)
  532.  
  533. # Return reference to this variable for the user
  534. return v
  535. end
  536.  
  537. #-----------------------------------------------------------------
  538. # EXPERIMENTAL METHODS FOR FUTURE RELEASE
  539. #-----------------------------------------------------------------
  540.  
  541. #-----------------------------------------------------------#
  542. # make_duration_rel: Makes a duration based reliability column
  543. # based on John's method. It will create two new columns, one
  544. # that contains a cell with a number for that block, and another
  545. # blank column for the free coding within that block.
  546. #-----------------------------------------------------------#
  547.  
  548. #-------------------------------------------------------------------
  549. # Method name: makeDurationBlockRel
  550. # Function: Makes a duration based reliability column
  551. # based on John's method. It will create two new columns, one
  552. # that contains a cell with a number for that block, and another
  553. # blank column for the free coding within that block.
  554. # Arguments:
  555. # => relname (required): The name of the rel column to be made.
  556. # => var_to_copy (required): The name of the variable being copied.
  557. # => binding (required): The name of the variable to bind the copy to.
  558. # => block_dur (required): How long (in seconds) should the blocks be?
  559. # => skip_blocks (required): How many blocks of block_dur should we skip between
  560. # each coding block?
  561. #
  562. # # Returns:
  563. # => Nothing. Variables are written to the database.
  564. # #-------------------------------------------------------------------
  565. def makeDurationBlockRel(relname, var_to_copy, binding, block_dur, skip_blocks)
  566. block_var = createNewVariable(relname + "_blocks", "block_num")
  567. rel_var = make_rel(relname, var_to_copy, 0)
  568.  
  569. var_to_copy = getVariable(var_to_copy)
  570. binding = getVariable(binding)
  571.  
  572.  
  573. block_dur = block_dur * 1000 # Convert to milliseconds
  574. block_num = 1
  575. for bindcell in binding.cells
  576. cell_dur = bindcell.offset - bindcell.onset
  577. if cell_dur <= block_dur
  578. cell = block_var.make_new_cell()
  579. cell.change_arg("block_num", block_num.to_s)
  580. cell.change_arg("onset", bindcell.onset)
  581. cell.change_arg("offset", bindcell.offset)
  582. block_num += 1
  583. else
  584. num_possible_blocks = cell_dur / block_dur #Integer division
  585. if num_possible_blocks > 0
  586. for i in 0..num_possible_blocks
  587. if i % skip_blocks == 0
  588. cell = block_var.make_new_cell()
  589. cell.change_arg("block_num", block_num.to_s)
  590. cell.change_arg("onset", bindcell.onset + i * block_dur)
  591. if bindcell.onset + (i + 1) * block_dur <= bindcell.offset
  592. cell.change_arg("offset", bindcell.onset + (i + 1) * block_dur)
  593. else
  594. cell.change_arg("offset", bindcell.offset)
  595. end
  596. block_num += 1
  597. end
  598. end
  599. end
  600. end
  601. end
  602. setVariable(relname + "_blocks", block_var)
  603. end
  604.  
  605. #-------------------------------------------------------------------
  606. # Method name: add_args_to_var
  607. # Function: Add new arguments to any variable
  608. # Arguments:
  609. # => var (required): The variable to add args to. This can be a name or a variable object.
  610. # => *args (required): A list of the arguments to add to var (can be any number of args)
  611. #
  612. # Returns:
  613. # => The new Ruby representation of the variable. Write it back to the database
  614. # to save it.
  615. #
  616. # Example:
  617. # test = add_args_to_var("test", "arg1", "arg2", "arg3")
  618. # setVariable("test",test)
  619. # -------------------------------------------------------------------
  620. def add_args_to_var(var, *args)
  621. if var.class == "".class
  622. var = getVariable(var)
  623. end
  624.  
  625. var_new = createNewVariable(var.name, var.arglist + args)
  626.  
  627. for cell in var.cells
  628. new_cell = var_new.make_new_cell()
  629. new_cell.change_arg("onset", cell.onset)
  630. new_cell.change_arg("offset", cell.offset)
  631. for arg in var.arglist
  632. v = eval "cell.#{arg}"
  633. new_cell.change_arg(arg, v)
  634. end
  635. end
  636.  
  637. return var_new
  638. end
  639.  
  640. #-------------------------------------------------------------------
  641. # Method name: create_mutually_exclusive
  642. # Function: Create a new column from two others, mixing their cells together
  643. # such that the new variable has all of the arguments of both other variables
  644. # and a new cell for each overlap and mixture of the two cells. Mixing two
  645. # variables together.
  646. # Arguments:
  647. # => name (required): The name of the new variable.
  648. # => var1name (required): Name of the first variable to be mutexed.
  649. # => var2name (required): Name of the second variable to be mutexed.
  650. #
  651. # Returns:
  652. # => The new Ruby representation of the variable. Write it back to the database
  653. # to save it.
  654. #
  655. # Example:
  656. # test = create_mutually_exclusive("test", "var1", "var2")
  657. # setVariable("test",test)
  658. # -------------------------------------------------------------------
  659. def create_mutually_exclusive(name, var1name, var2name)
  660. if var1name.class == "".class
  661. var1 = getVariable(var1name)
  662. end
  663. if var2name.class == "".class
  664. var2 = getVariable(var2name)
  665. end
  666.  
  667. var1_argprefix = var1.name.gsub(/(\W)+/,"").downcase + "_"
  668. var2_argprefix = var2.name.gsub(/(\W)+/,"").downcase + "_"
  669. puts var2_argprefix
  670.  
  671. var1_argprefix.gsub(".", "")
  672. var2_argprefix.gsub(".","")
  673.  
  674. v1arglist = var1.arglist.map { |arg| var1_argprefix + arg }
  675. v2arglist = var2.arglist.map { |arg| var2_argprefix + arg }
  676.  
  677. puts v1arglist, v2arglist
  678. args = Array.new
  679. args << (var1_argprefix + "ordinal")
  680. args += v1arglist
  681.  
  682. args << (var2_argprefix + "ordinal")
  683. args += v2arglist
  684.  
  685. puts "Creating mutex var", var1.arglist
  686. mutex = createNewVariable(name, args)
  687. puts "Mutex var created"
  688.  
  689. # Now we have to go thru var1 and var2 and modify the argument names
  690.  
  691. usedV1Cells = Array.new
  692. usedV2Cells = Array.new
  693. for i in 0..var1.cells.length - 1
  694. v1cell = var1.cells[i]
  695. prev_over = false
  696. within = false
  697. next_over = false
  698.  
  699. # Figure out the cell relations
  700. for v2cell in var2.cells
  701. if v1cell.onset > v2cell.onset and v1cell.onset < v2cell.offset \
  702. and v1cell.offset > v2cell.offset
  703. prev_over = v2cell
  704. elsif v2cell.onset >= v1cell.onset and v2cell.onset <= v1cell.offset \
  705. and v2cell.offset <= v1cell.offset and v2cell.offset >= v1cell.onset
  706. if within == false
  707. within = Array.new
  708. end
  709. within << v2cell
  710. elsif v1cell.offset > v2cell.onset and v1cell.offset < v2cell.offset \
  711. and v1cell.onset < v2cell.onset
  712. next_over = v2cell
  713. end
  714. end
  715. v1_new_onset = v1cell.onset
  716. v1_new_offset = 0
  717.  
  718. puts "Finding and adding previous crossover cells"
  719. # Create the prev cells
  720. if prev_over != false
  721. # Make the cell that overlaps the beginning of this one
  722.  
  723. # This is the overlap cell
  724. cell2 = mutex.make_new_cell()
  725. cell2.change_arg("onset", v1cell.onset)
  726. cell2.change_arg("offset", prev_over.offset)
  727. for arg in mutex.arglist
  728. v = nil
  729. if arg.index(var2_argprefix) == 0
  730.  
  731. a = arg.gsub(var2_argprefix, "")
  732. puts "Argname:" + arg
  733. v = eval "prev_over.#{a}"
  734. elsif arg.index(var1_argprefix) == 0
  735.  
  736. a = arg.gsub(var1_argprefix, "")
  737. puts "Argname:" + arg
  738. v = eval "v1cell.#{a}"
  739. end
  740. cell2.change_arg(arg, v)
  741. end
  742.  
  743. # cell3 = mutex.make_new_cell()
  744. # cell3.change_arg("onset", v1cell.offset)
  745. # cell3.change_arg("offset", prev_over.offset)
  746. v1_new_onset = prev_over.offset + 1
  747.  
  748. printf("PREV V1:on=%d off=%d, cell1:on=%d off=%d\n", \
  749. v1cell.onset, v1cell.offset, cell2.onset, cell2.offset)
  750.  
  751. # printf("PREV V1:on=%d off=%d, cell1:on=%d off=%d, cell2:on=%d off=%d\n", \
  752. # v1cell.onset, v1cell.offset, cell1.onset, cell1.offset, cell2.onset, cell2.offset)
  753.  
  754. usedV2Cells << prev_over
  755. end
  756.  
  757. puts "Finding and adding cells within cells"
  758. if within != false
  759. # Make cells for each cell within the main cell
  760. for wcell in within
  761.  
  762. cell1 = mutex.make_new_cell()
  763. cell1.change_arg("onset", wcell.onset)
  764. cell1.change_arg("offset", wcell.offset)
  765. for arg in mutex.arglist
  766. v = nil
  767. if arg.index(var2_argprefix) == 0
  768. a = arg.gsub(var2_argprefix, "")
  769. v = eval "wcell.#{a}"
  770. elsif arg.index(var1_argprefix) == 0
  771. a = arg.gsub(var1_argprefix, "")
  772. v = eval "v1cell.#{a}"
  773. end
  774. cell1.change_arg(arg, v)
  775. end
  776.  
  777. printf("WITHIN V2:on=%d off=%d, cell1:on=%d off=%d, new:on=%d, off=:%d\n", \
  778. v1cell.onset, v1cell.offset, cell1.onset, cell1.offset, wcell.onset, wcell.offset)
  779.  
  780. usedV2Cells << wcell
  781. usedV1Cells << v1cell
  782. end
  783. end
  784.  
  785. puts "Finding and adding next crossing cells for onset V1: onset=" + v1cell.onset.to_s + " off=" + v1cell.offset.to_s
  786. if next_over != false
  787. # Make cells for cell overlapping end
  788. cell1 = mutex.make_new_cell()
  789. cell1.change_arg("onset", next_over.onset)
  790. cell1.change_arg("offset", v1cell.offset)
  791. for arg in mutex.arglist
  792. v = nil
  793. if arg.index(var2_argprefix) == 0
  794. a = arg.gsub(var2_argprefix, "")
  795. v = eval "next_over.#{a}"
  796. elsif arg.index(var1_argprefix) == 0
  797. a = arg.gsub(var1_argprefix, "")
  798. v = eval "v1cell.#{a}"
  799. end
  800. puts arg, v
  801. cell1.change_arg(arg, v)
  802. end
  803.  
  804. # cell2 = mutex.make_new_cell()
  805. # cell2.change_arg("onset", v1cell.offset)
  806. # cell2.change_arg("offset", next_over.offset)
  807.  
  808. v1_new_onset = next_over.onset + 1
  809.  
  810. usedV2Cells << next_over
  811.  
  812. # printf("NEXT V1:on=%d off=%d, cell1:on=%d off=%d, cell2:on=%d off=%d\n", \
  813. # v1cell.onset, v1cell.offset, cell1.onset, cell1.offset, cell2.onset, cell2.offset)
  814. printf("NEXT V1:on=%d off=%d, cell1:on=%d off=%d\n", \
  815. v1cell.onset, v1cell.offset, cell1.onset, cell1.offset)
  816. end
  817. if prev_over != false or within != false or next_over != false
  818. usedV1Cells << v1cell
  819. end
  820. end
  821.  
  822. puts "Adding V2 within cells"
  823. # Now add in the v1 cells that are within v2 cells
  824. for i in 0..var2.cells.length - 1
  825. within = Array.new
  826. v2cell = var2.cells[i]
  827.  
  828. for v1cell in var1.cells
  829. if v1cell.onset >= v2cell.onset and v1cell.onset <= v2cell.offset \
  830. and v1cell.offset <= v2cell.offset and v1cell.offset >= v2cell.onset \
  831. and not (v1cell.onset == v2cell.onset and v1cell.offset == v2cell.offset)
  832. within << v1cell
  833. end
  834. end
  835.  
  836. if within.length > 0
  837. # Make cells for each cell within the main cell
  838. for wcell in within
  839.  
  840. cell1 = mutex.make_new_cell()
  841. cell1.change_arg("onset", wcell.onset)
  842. cell1.change_arg("offset", wcell.offset)
  843. for arg in mutex.arglist
  844. v = nil
  845. if arg.index(var1_argprefix) == 0
  846.  
  847. a = arg.gsub(var1_argprefix, "")
  848. v = eval "wcell.#{a}"
  849. elsif arg.index(var2_argprefix) == 0
  850.  
  851. a = arg.gsub(var2_argprefix, "")
  852. v = eval "v2cell.#{a}"
  853. end
  854. cell1.change_arg(arg, v)
  855. end
  856.  
  857. printf("WITHIN V2:on=%d off=%d, cell1:on=%d off=%d, new:on=%d, off=:%d\n", \
  858. v1cell.onset, v1cell.offset, cell1.onset, cell1.offset, wcell.onset, wcell.offset)
  859.  
  860. usedV1Cells << wcell
  861. usedV2Cells << v2cell
  862. end
  863. end
  864.  
  865. end
  866.  
  867. puts "Erasing dupes."
  868. # Erase dupes
  869. usedV1Cells.uniq!
  870. usedV2Cells.uniq!
  871.  
  872. for c in usedV2Cells
  873. var2.cells.delete(c)
  874. end
  875. for c in usedV1Cells
  876. var1.cells.delete(c)
  877. end
  878. for c in var1.cells
  879. cell = mutex.make_new_cell()
  880. cell.change_arg("onset", c.onset)
  881. cell.change_arg("offset", c.offset)
  882. for arg in mutex.arglist
  883. if arg.index(var1_argprefix) == 0
  884.  
  885. puts "C:",arg, v, c.arglist
  886.  
  887. a = arg.gsub(var1_argprefix, "")
  888. v = eval "c.#{a}"
  889. cell.change_arg(arg, v)
  890. end
  891. end
  892. end
  893. for c in var2.cells
  894. cell = mutex.make_new_cell()
  895. cell.change_arg("onset", c.onset)
  896. cell.change_arg("offset", c.offset)
  897. for arg in mutex.arglist
  898. if arg.index(var2_argprefix) == 0
  899.  
  900. puts arg, v, c.arglist
  901.  
  902. a = arg.gsub(var2_argprefix, "")
  903. v = eval "c.#{a}"
  904. cell.change_arg(arg, v)
  905. end
  906. end
  907. end
  908.  
  909. # Now we sort the cells in mutex so we can
  910. # search thru what we have and add in blocks
  911. mutex.sort_cells()
  912.  
  913. # Calculate and add cells for gaps in v1
  914. var1 = getVariable(var1name)
  915.  
  916.  
  917. for v1cell in var1.cells
  918. dirty = false
  919. for i in 0...mutex.cells.length-1
  920. if dirty == true
  921. mutex.sort_cells()
  922. dirty = false
  923. end
  924. mcell_cur = mutex.cells[i]
  925. mcell_next = mutex.cells[i+1]
  926. # puts "V1:" + v1cell.onset.to_s + " " + v1cell.offset.to_s
  927. # puts mcell_cur.onset.to_s + " " + mcell_cur.offset.to_s \
  928. # + "/" + mcell_next.onset.to_s + " " + mcell_next.offset.to_s
  929.  
  930. v1range = (v1cell.onset..v1cell.offset)
  931. if v1range.include?(mcell_cur.onset) and \
  932. v1range.include?(mcell_cur.offset) and \
  933. v1range.include?(mcell_next.onset) and \
  934. v1range.include?(mcell_next.offset)
  935.  
  936. if mcell_cur.offset + 1 < mcell_next.onset - 1
  937. cell = mutex.make_new_cell()
  938. cell.change_arg("onset", mcell_cur.offset + 1)
  939. cell.change_arg("offset", mcell_next.onset - 1)
  940. for arg in mutex.arglist
  941. a = arg.gsub(var1_argprefix, "")
  942. if arg.index(var1_argprefix) == 0
  943.  
  944. puts "ONE SIDE +1-1:", arg, v, cell.onset, cell.offset
  945. v = eval "v1cell.#{a}"
  946. cell.change_arg(arg, v)
  947. dirty = true
  948. end
  949. end
  950. end
  951. elsif v1range.include?(mcell_cur.onset) and \
  952. v1range.include?(mcell_cur.offset) and \
  953. mcell_next.onset - 1 > mcell_cur.offset
  954.  
  955. if mcell_cur.onset == v1cell.onset
  956. if mcell_cur.offset + 1 < v1cell.offset
  957. cell = mutex.make_new_cell()
  958. cell.change_arg("onset", mcell_cur.offset + 1)
  959. cell.change_arg("offset", v1cell.offset)
  960. for arg in mutex.arglist
  961. a = arg.gsub(var1_argprefix, "")
  962. if arg.index(var1_argprefix) == 0
  963.  
  964. puts "ONE SIDE ==on:" , arg, v, v1cell.arglist, cell.onset, cell.offset
  965. v = eval "v1cell.#{a}"
  966. cell.change_arg(arg, v)
  967. dirty = true
  968. end
  969. end
  970. end
  971. # elsif mcell_cur.offset == v1cell.offset
  972. # if v1cell.onset < mcell_cur.onset - 1
  973. # cell = mutex.make_new_cell()
  974. # cell.change_arg("onset", v1cell.onset)
  975. # cell.change_arg("offset", mcell_cur.onset - 1)
  976. # for arg in mutex.arglist
  977. # a = arg.gsub(var1_argprefix, "")
  978. # if arg.include?(var1_argprefix)
  979. # v = eval "v1cell.#{a}"
  980. # puts "ONE SIDE ==off:", arg, v, v1cell.onset, v1cell.offset, cell.onset, cell.offset, mcell_cur.onset, mcell_cur.offset
  981. # cell.change_arg(arg, v)
  982. # dirty = true
  983. # end
  984. # end
  985. # end
  986. end
  987. end
  988. end
  989. end
  990.  
  991. mutex.sort_cells()
  992. var2 = getVariable(var2name)
  993.  
  994. for v2cell in var2.cells
  995. dirty = false
  996. for i in 0...mutex.cells.length-1
  997. if dirty == true
  998. mutex.sort_cells()
  999. dirty = false
  1000. end
  1001. mcell_cur = mutex.cells[i]
  1002. mcell_next = mutex.cells[i+1]
  1003. # puts "V2:" + v2cell.onset.to_s + " " + v2cell.offset.to_s
  1004. # puts mcell_cur.onset.to_s + " " + mcell_cur.offset.to_s \
  1005. # + "/" + mcell_next.onset.to_s + " " + mcell_next.offset.to_s
  1006.  
  1007. v2range = (v2cell.onset..v2cell.offset)
  1008. if v2range.include?(mcell_cur.onset) and \
  1009. v2range.include?(mcell_cur.offset) and \
  1010. v2range.include?(mcell_next.onset) and \
  1011. v2range.include?(mcell_next.offset)
  1012.  
  1013. if mcell_cur.offset + 1 < mcell_next.onset - 1
  1014. cell = mutex.make_new_cell()
  1015. cell.change_arg("onset", mcell_cur.offset + 1)
  1016. cell.change_arg("offset", mcell_next.onset - 1)
  1017. for arg in mutex.arglist
  1018. a = arg.gsub(var2_argprefix, "")
  1019. if arg.index(var2_argprefix) == 0
  1020.  
  1021. v = eval "v2cell.#{a}"
  1022. puts "V2 Single:", arg, v, v2cell.arglist, cell.onset, cell.offset
  1023. cell.change_arg(arg, v)
  1024. dirty = true
  1025. end
  1026. end
  1027. end
  1028. elsif v2range.include?(mcell_cur.onset) and \
  1029. v2range.include?(mcell_cur.offset) and \
  1030. mcell_next.onset - 1 > mcell_cur.offset
  1031.  
  1032. if mcell_cur.onset == v2cell.onset
  1033. if mcell_cur.offset + 1 < v2cell.offset
  1034. cell = mutex.make_new_cell()
  1035. cell.change_arg("onset", mcell_cur.offset + 1)
  1036. cell.change_arg("offset", v2cell.offset)
  1037. for arg in mutex.arglist
  1038. a = arg.gsub(var2_argprefix, "")
  1039. if arg.index(var2_argprefix) == 0
  1040.  
  1041. v = eval "v2cell.#{a}"
  1042. puts "V2 Single:",arg, v, v2cell.arglist, cell.onset, cell.offset
  1043. cell.change_arg(arg, v)
  1044. dirty = true
  1045. end
  1046. end
  1047. end
  1048. end
  1049. if mcell_next.offset == v2cell.offset
  1050. if v2cell.onset < mcell_next.onset - 1
  1051.  
  1052.  
  1053. cell = mutex.make_new_cell()
  1054. cell.change_arg("onset", v2cell.onset)
  1055. cell.change_arg("offset", mcell_next.onset - 1)
  1056. for arg in mutex.arglist
  1057. a = arg.gsub(var2_argprefix, "")
  1058. if arg.index(var2_argprefix) == 0
  1059.  
  1060. v = eval "v2cell.#{a}"
  1061. puts "V2 Single:", arg, v, v2cell.arglist, cell.onset, cell.offset
  1062. cell.change_arg(arg, v)
  1063. dirty = true
  1064. end
  1065. end
  1066. end
  1067. end
  1068. end
  1069. end
  1070. end
  1071.  
  1072. mutex.sort_cells()
  1073.  
  1074. puts "MUTEX FINISHED"
  1075.  
  1076. return mutex
  1077.  
  1078. # Have it write ordinals in at end
  1079. # Have it put ordinals of original cells in
  1080. # Have it have two arguments to name the prefixes for the arguments
  1081. #
  1082. end
  1083.  
  1084. #-------------------------------------------------------------------
  1085. # Method name: load_db
  1086. # Function: Loads a new database from a file. DOES NOT ALTER THE GUI.
  1087. # Arguments:
  1088. # => filename (required): The FULL PATH to the saved OpenSHAPA file.
  1089. #
  1090. # Returns:
  1091. # => db: The database of the opened project. Set to $db to use other
  1092. # functions with it.
  1093. # => pj: The project data of the opened project. Set to $pj to use other
  1094. # functions with it.
  1095. #
  1096. # Example:
  1097. # $db,$pj = load_db("/Users/username/Desktop/test.opf")
  1098. # -------------------------------------------------------------------
  1099.  
  1100. def load_db(filename)
  1101. # Packages needed for opening and saving projects and databases.
  1102.  
  1103.  
  1104. #
  1105. # ****************************************************************************
  1106. # *** Check to make sure filename below is the absolute path to a project. ***
  1107. # ****************************************************************************
  1108. #
  1109. #
  1110. # Main body of example script:
  1111. #
  1112. puts "Opening Project: "
  1113.  
  1114. # Create the controller that holds all the logic for opening projects and
  1115. # databases.
  1116. open_c = OpenC.new
  1117.  
  1118. #
  1119. # Opens a project and associated database (i.e. either compressed or
  1120. # uncompressed .shapa files). If you want to just open a standalone database
  1121. # (i.e .odb or .csv file) call open_c.open_database("filename") instead. These
  1122. # methods do *NOT* open the project within the OpenSHAPA UI.
  1123. #
  1124. db = nil
  1125. proj = nil
  1126. if filename.include?(".csv")
  1127. open_c.open_database(filename)
  1128. else
  1129. open_c.open_project(filename)
  1130. # Get the project that was opened (if you want).
  1131. proj = open_c.get_project
  1132. end
  1133.  
  1134. # Get the database that was opened.
  1135. db = open_c.get_database
  1136.  
  1137.  
  1138. # If the open went well - query the database, do calculations or whatever
  1139. unless db.nil?
  1140. # This just prints the number of columns in the database.
  1141. puts "Opened a project with '" + db.get_columns.length.to_s + "' columns!"
  1142. else
  1143. puts "Unable to open the project '" + filename + "'"
  1144. end
  1145.  
  1146. puts filename + " has been loaded."
  1147.  
  1148. return db, proj
  1149. end
  1150.  
  1151.  
  1152. #-------------------------------------------------------------------
  1153. # Method name: save_db
  1154. # Function: Saves the current $db and $pj variables to filename. If
  1155. # filename ends with .csv, it saves a .csv file. Otherwise it saves
  1156. # it as a .opf.
  1157. # Arguments:
  1158. # => filename (required): The FULL PATH to where the OpenSHAPA file should
  1159. # be saved.
  1160. #
  1161. # Returns:
  1162. # => Nothing.
  1163. #
  1164. # Example:
  1165. # save_db("/Users/username/Desktop/test.opf")
  1166. # -------------------------------------------------------------------
  1167. def save_db(filename)
  1168. #
  1169. # Main body of example script:
  1170. #
  1171. puts "Saving Database: " + filename
  1172.  
  1173. # Create the controller that holds all the logic for opening projects and
  1174. # databases.
  1175. save_c = SaveC.new
  1176.  
  1177. #
  1178. # Saves a database (i.e. a .odb or .csv file). If you want to save a project
  1179. # call save_project("project file", project, database) instead.
  1180. # These methods do *NOT* alter the OpenSHAPA UI.
  1181. #
  1182. if filename.include?('.csv')
  1183. save_c.save_database(filename, $db)
  1184. else
  1185. #if $pj == nil or $pj.getDatabaseFileName == nil
  1186. $pj = Project.new()
  1187. $pj.setDatabaseFileName("db")
  1188. dbname = filename[filename.rindex("/")+1..filename.length]
  1189. $pj.setProjectName(dbname)
  1190. #end
  1191. save_file = java.io.File.new(filename)
  1192. save_c.save_project(save_file, $pj, $db)
  1193. end
  1194.  
  1195. puts "Save successful."
  1196.  
  1197. end
  1198.  
  1199. def delete_column(colname)
  1200. col = $db.get_column(colname)
  1201. numcells = col.get_num_cells
  1202. numcells.downto(1) do |i|
  1203. $db.remove_cell($db.get_cell(col.get_id, i).get_id)
  1204. end
  1205. $db.remove_column(col.get_id)
  1206. end
  1207.  
  1208.  
  1209. #-------------------------------------------------------------------
  1210. # Method name: load_macshapa_db
  1211. # Function: Opens an old, closed database format MacSHAPA file and loads
  1212. # it into the current open database.
  1213. #
  1214. # WARNING: This will only read in
  1215. # matrix and string variables. Predicates are not yet supported.
  1216. # Queries will not be read in. Times are translated to milliseconds
  1217. # for compatibility with OpenSHAPA.
  1218. # Arguments:
  1219. # => filename (required): The FULL PATH to the saved MacSHAPA file.
  1220. # => write_to_gui (required): Whether the MacSHAPA file should be read into
  1221. # the database currently open in the GUI or whether it should just be
  1222. # read into the Ruby interface. After this script is run $db and $pj
  1223. # are now the MacSHAPA file.
  1224. #
  1225. # Returns:
  1226. # => db: The database of the opened project.
  1227. # => pj: The project data of the opened project.
  1228. #
  1229. # Example:
  1230. # $db,$pj = load_db("/Users/username/Desktop/test.opf")
  1231. # -------------------------------------------------------------------
  1232. def load_macshapa_db(filename, write_to_gui)
  1233.  
  1234.  
  1235. # Create a new DB for us to use so we don't touch the GUI... some of these
  1236. # files can be huge.
  1237. # Since I don't know how to make a whole new project, lets just load a blank file.
  1238. if not write_to_gui
  1239. #$db,$pj = load_db("/Users/j4lingeman/Desktop/blank.opf")
  1240. $db = MacshapaDatabase.new(1000)
  1241. $pj = Project.new()
  1242. end
  1243.  
  1244.  
  1245.  
  1246. f = File.open(filename, 'r')
  1247.  
  1248. # Read and split file by lines. '\r' is used because that is the default
  1249. # format for OS9 files.
  1250. file = f.gets
  1251. lines = file.split(/\r/)
  1252.  
  1253. # Find the variable names in the file and use these to create and set up
  1254. # our columns.
  1255. predIndex = lines.index("***Predicates***")
  1256. varIndex = lines.index("***Variables***")
  1257. spreadIndex = lines.index("***SpreadPane***")
  1258. predIndex += 2
  1259.  
  1260. variables = Hash.new
  1261. varIdent = Array.new
  1262.  
  1263. while predIndex < varIndex
  1264. l = lines[predIndex].split(/ /)[5]
  1265. varname = l[0..l.index("(") - 1]
  1266. if varname != "###QueryVar###" and varname != "div" and varname != "qnotes"
  1267. variables[varname] = l[l.index("(")+1..l.length-2].split(/,/)
  1268. varIdent << l
  1269. end
  1270. predIndex += 1
  1271. end
  1272.  
  1273. # Create the columns for the variables
  1274. variables.each do |key, value|
  1275. # Create column
  1276. if !$db.col_name_in_use(key)
  1277. col = DataColumn.new($db, key, MatrixVocabElement::MatrixType::MATRIX)
  1278. $db.add_column(col)
  1279. end
  1280.  
  1281. mve0 = $db.get_vocab_element(key)
  1282. if mve0.get_num_formal_args() == 1
  1283. # Setup structure of matrix column
  1284. mve0 = MatrixVocabElement.new(mve0)
  1285. mve0.delete_formal_arg(0)
  1286. value.each { |v|
  1287. # Strip out the ordinal, onset, and offset. These will be handled on a
  1288. # cell by cell basis.
  1289. if v != "<ord>" and v != "<onset>" and v != "<offset>"
  1290. #puts v
  1291. farg = NominalFormalArg.new($db, v)
  1292. mve0.append_formal_arg(farg)
  1293. end
  1294. }
  1295. $db.replace_matrix_ve(mve0)
  1296. end
  1297. end
  1298.  
  1299. # Search for where in the file the var's cells are, create them, then move
  1300. # on to the next variable.
  1301. varSection = lines[varIndex..spreadIndex]
  1302.  
  1303. varIdent.each do |id|
  1304. col = $db.get_column(id[0..id.index("(")-1])
  1305. mve = $db.get_matrix_ve(col.its_mve_id)
  1306. matid = mve.get_id()
  1307.  
  1308. # Search the variable section for the above id
  1309. varSection.each do |l|
  1310. line = l.split(/[\t\s]/)
  1311. if line[2] == id
  1312. #puts varname
  1313. start = varSection.index(l) + 1
  1314.  
  1315. stringCol = false
  1316.  
  1317. if varSection[start - 2].index("strID") != nil
  1318. stringCol = true
  1319. end
  1320.  
  1321. #Found it! Now build the cells
  1322. while varSection[start] != "0"
  1323. varSection[start]
  1324. if stringCol == false
  1325. cellData = varSection[start].split(/[\t]/)
  1326. cellData[cellData.length - 1] = cellData[cellData.length-1][cellData[cellData.length-1].index("(")..cellData[cellData.length-1].length]
  1327.  
  1328. else
  1329. cellData = varSection[start].split(/[\t]/)
  1330. end
  1331.  
  1332. # Init cell to null
  1333. cell = DataCell.new($db, col.get_id, mve.get_id)
  1334. mat = Matrix.new($db, matid)
  1335.  
  1336. # Convert onset/offset from 60 ticks/sec to milliseconds
  1337. onset = cellData[0].to_i / 60.0 * 1000
  1338. offset = cellData[1].to_i / 60.0 * 1000
  1339.  
  1340. # Set onset/offset of cell
  1341. cell.onset = TimeStamp.new(1000, onset.round)
  1342. cell.offset = TimeStamp.new(1000, offset.round)
  1343.  
  1344. # Split up cell data
  1345. data = cellData[cellData.length - 1]
  1346. if stringCol == false
  1347. data = data[1..data.length-2]
  1348. data = data.gsub(/[() ]*/, "")
  1349. data = data.split(/,/)
  1350. elsif data != nil #Then this is a string var
  1351. data = data.strip()
  1352. if data.split(" ").length > 1
  1353. data = data[data.index(" ")..data.length] # Remove the char count
  1354. data = data.gsub("/", " or ")
  1355. data = data.gsub(/[^\w ]*/, "")
  1356. data = data.gsub(/ /," ")
  1357. else
  1358. data = ""
  1359. end
  1360. else
  1361. data = Array.new
  1362. data << nil
  1363. end
  1364.  
  1365. # Cycle thru cell data arguments and fill them into the cell matrix
  1366. narg = 0
  1367. data.each do |d|
  1368. fargid = mve.get_formal_arg(narg).get_id()
  1369. d = d.strip()
  1370. if d == "" or d == nil or d.index("<") != nil
  1371. fdv = NominalDataValue.new($db, fargid)
  1372. fdv.clearValue()
  1373. else
  1374. d = d.strip()
  1375. fdv = NominalDataValue.new($db, fargid, d)
  1376. end
  1377. mat.replaceArg(narg,fdv)
  1378. narg += 1
  1379. end
  1380.  
  1381. # Put cell into database
  1382. cell.set_val(mat)
  1383. $db.append_cell(cell)
  1384. start += 1
  1385. end
  1386. end
  1387. end
  1388. end
  1389.  
  1390. f.close()
  1391.  
  1392. return $db, $pj
  1393. end
  1394.  
  1395. #-------------------------------------------------------------------
  1396. # Method name: transfer_columns
  1397. # Function: Transfers columns between databases. If db1 or db2 are set
  1398. # to the empty string "", then that database is the current database
  1399. # in $db (usually the GUI's database). So if you want to transfer a
  1400. # column into the GUI, set db2 to "". If you want to tranfer a column
  1401. # from the GUI into a file, set db1 to "". Setting remove to true will
  1402. # DELETE THE COLUMNS YOU ARE TRANSFERRING FROM DB1. Be careful!
  1403. # Arguments:
  1404. # => db1 (required): The FULL PATH to the saved OpenSHAPA file or set to
  1405. # "" to use the currently opened database. Columns are transferred FROM here.
  1406. # => db2 (required): The FULL PATH to the saved OpenSHAPA file or set to
  1407. # "" to use the currently opened database. Columns are tranferred TO here.
  1408. # => remove (required): Set to true to delete columns in DB1 as they are moved to
  1409. # db2. Set to false to leave them intact.
  1410. # => varnames (requires at least 1): You can specify as many var names as you like
  1411. # that will be retrieved from db1. These should be the string names of the
  1412. # variables.
  1413. #
  1414. # Returns:
  1415. # => Nothing. Saves the files in place or modifies the GUI
  1416. #
  1417. # Example:
  1418. # transfer_columns("/Users/username/Desktop/test.opf","",true,"idchange")
  1419. # The above example will transfer the column "idchange" from test.opf to the GUI
  1420. # and leave test.opf intact with no modifications.
  1421. # -------------------------------------------------------------------
  1422. def transfer_columns(db1, db2, remove, *varnames)
  1423. puts "Transfering the following columns from " + db1 + " to " + db2 + ":"
  1424. puts varnames
  1425.  
  1426. if remove
  1427. puts "WARNING: These columns will be deleted from " + db1
  1428. end
  1429.  
  1430. if db1 == ""
  1431. from_db = $db
  1432. from_pj = $pj
  1433. else
  1434. from_db, from_pj = load_db(db1)
  1435. end
  1436.  
  1437. if db2 == ""
  1438. to_db = $db
  1439. to_pj = $pj
  1440. else
  1441. to_db, to_pj = load_db(db2)
  1442. end
  1443.  
  1444. # Get from DB1
  1445. $db, $pj = from_db, from_pj
  1446. vars_to_trans = Array.new
  1447. for v in varnames
  1448. vars_to_trans << getVariable(v)
  1449. end
  1450.  
  1451. # Transfer to DB2
  1452. $db, $pj = to_db, to_pj
  1453. for i in 0...vars_to_trans.length
  1454. setVariable(varnames[i],vars_to_trans[i])
  1455. end
  1456. if db2 != ""
  1457. puts "Saving " + db2
  1458. save_db(db2)
  1459. end
  1460.  
  1461. # Removing columns should be the last thing we do in case anything goes wrong
  1462. # We don't want to lose a column for any reason.
  1463. if remove
  1464. $db, $pj = from_db, from_pj
  1465. if remove
  1466. for v in varnames
  1467. delete_column(v)
  1468. end
  1469. end
  1470. if db1 != ""
  1471. puts "Saving " + db1
  1472. save_db(db1)
  1473. end
  1474. end
  1475.  
  1476. puts "Columns transferred successfully."
  1477. end
  1478.  
  1479.  
  1480. #-------------------------------------------------------------------
  1481. # Method name: check_rel
  1482. # Function: Do a quick, in OpenSHAPA, check of reliability errors.
  1483. # Arguments:
  1484. # => main_col (required): Either the string name or the Ruby column from getVariable
  1485. # of the primary column to compare against.
  1486. # => rel_col (required): Either the string name or the Ruby column from getVariable
  1487. # of the reliability column to compare to the primary column.
  1488. # => match_arg (required): The string of the argument to use to match the relability
  1489. # cells to the primary cells. This must be a unique identifier between the cells.
  1490. # => time_tolerance (required): The amount of slack you allow, in milliseconds, for
  1491. # difference between onset and offset before it is considered an error. Set to 0
  1492. # for no difference allowed and to a very large number for infinite distance allowed.
  1493. # => dump_file (optional): The full string path to dump the relability output to. This
  1494. # can be used for multi-file dumps or just to keep a log. You can also give it a Ruby
  1495. # File object if a file is already started.
  1496. #
  1497. # Returns:
  1498. # => Nothing but the console and file output.
  1499. #
  1500. # Example:
  1501. # check_rel("trial", "rel.trial", "trialnum", 100, "/Users/motoruser/Desktop/Relcheck.txt")
  1502. # or
  1503. # check_rel("trial", "rel.trial", "trialnum", 100)
  1504. # -------------------------------------------------------------------
  1505. def check_rel(main_col, rel_col, match_arg, time_tolerance, *dump_file)
  1506. # Make the match_arg conform to the method format that is used
  1507. if ["0","1","2","3","4","5","6","7","8","9"].include?(match_arg[0].chr)
  1508. match_arg = match_arg[1..match_arg.length]
  1509. end
  1510. match_arg = match_arg.gsub(/(\W)+/,"").downcase
  1511.  
  1512. # Set up our method variables
  1513. dump_file = dump_file[0]
  1514. if main_col.class == "".class
  1515. main_col = getVariable(main_col)
  1516. end
  1517. if rel_col.class == "".class
  1518. rel_col = getVariable(rel_col)
  1519. end
  1520.  
  1521. printing = false
  1522. if dump_file != nil
  1523. if dump_file.class == "".class
  1524. dump_file = open(dump_file,'a')
  1525. end
  1526. printing = true
  1527. end
  1528.  
  1529. # Define interal function for printing errors
  1530. def print_err(m_cell, r_cell, arg, dump_file, main_col, rel_col)
  1531. main_val = eval "m_cell.#{arg}"
  1532. rel_val = eval "r_cell.#{arg}"
  1533. err_str = "ERROR in " + main_col.name + " at Ordinal " + m_cell.ordinal.to_s + ", rel ordinal " + r_cell.ordinal.to_s + " in argument " + arg + ": " + main_val.to_s + ", " + rel_val.to_s + "\n"
  1534. if dump_file != nil
  1535. dump_file.write(err_str)
  1536. end
  1537. print err_str
  1538. end
  1539.  
  1540. # Build error array
  1541. errors = Hash.new
  1542. for arg in main_col.arglist
  1543. errors[arg] = 0
  1544. end
  1545. errors["onset"] = 0
  1546. errors["offset"] = 0
  1547.  
  1548. # Now check the cells
  1549. for mc in main_col.cells
  1550. main_bind = eval "mc.#{match_arg}"
  1551. for rc in rel_col.cells
  1552. rel_bind = eval "rc.#{match_arg}"
  1553. if main_bind == rel_bind
  1554. # Then check these cells match, check them for errors
  1555. if (mc.onset - rc.onset).abs >= time_tolerance
  1556. print_err(mc, rc, "onset", dump_file, main_col, rel_col)
  1557. errors["onset"] = errors["onset"] + 1
  1558. end
  1559. if (mc.offset - rc.offset).abs >= time_tolerance
  1560. print_err(mc, rc, "offset", dump_file, main_col, rel_col)
  1561. errors["offset"] = errors["offset"] + 1
  1562. end
  1563.  
  1564. for arg in main_col.arglist
  1565. main_val = eval "mc.#{arg}"
  1566. rel_val = eval "rc.#{arg}"
  1567. if main_val != rel_val
  1568. print_err(mc, rc, arg, dump_file, main_col, rel_col)
  1569. errors[arg] = errors[arg] + 1
  1570. end
  1571. end
  1572. end
  1573. end
  1574. end
  1575.  
  1576. for arg, errs in errors
  1577. str = "Total errors for " + arg + ": " + errs.to_s + ", Agreement:" + "%.2f" % (100 * (1.0 - (errs / rel_col.cells.length.to_f))) + "%\n"
  1578. print str
  1579. if dump_file != nil
  1580. dump_file.write(str)
  1581. dump_file.flush()
  1582. end
  1583. end
  1584. end
  1585.  
  1586. #-------------------------------------------------------------------
  1587. # Method name: check_valid_codes
  1588. # Function: Do a quick, in OpenSHAPA, check of valid codes.
  1589. # Arguments:
  1590. # => val (required): The variable that the codes belong to.
  1591. # => dump_file (required): The full path of the file to dump output to.
  1592. # Use "" to not dump to a file. You may also pass a Ruby File object.
  1593. # => arg_code_pairs (required): A list of the argument names and valid codes
  1594. # in the following format: "argument_name", ["y","n"], "argument2", ["j","k","m"]
  1595. # Returns:
  1596. # => Nothing but the console and file output.
  1597. #
  1598. # Example:
  1599. # check_valid_codes("trial", "", "hand", ["l","r","b","n"], "turn", ["l","r"], "unit", [1,2,3])
  1600. # -------------------------------------------------------------------
  1601.  
  1602. def check_valid_codes(var, dump_file, *arg_code_pairs)
  1603. if var.class == "".class
  1604. var = getVariable(var)
  1605. end
  1606.  
  1607. if dump_file != ""
  1608. if dump_file.class == "".class
  1609. dump_file = open(dump_file, 'a')
  1610. end
  1611. end
  1612.  
  1613. # Make the argument/code hash
  1614. arg_code = Hash.new
  1615. for i in 0...arg_code_pairs.length
  1616. if i % 2 == 0
  1617. if arg_code_pairs[i].class != "".class
  1618. puts 'FATAL ERROR in argument/valid code array. Exiting. Please check to make sure it is in the format "argumentname", ["valid","codes"]'
  1619. exit
  1620. end
  1621. arg = arg_code_pairs[i]
  1622. if ["0","1","2","3","4","5","6","7","8","9"].include?(arg[1].chr)
  1623. arg = arg[1..arg.length]
  1624. end
  1625. arg = arg.gsub(/(\W )+/,"").downcase
  1626.  
  1627. arg_code[arg] = arg_code_pairs[i+1]
  1628. end
  1629. end
  1630.  
  1631. errors = false
  1632. for cell in var.cells
  1633. for arg, code in arg_code
  1634. val = eval "cell.#{arg}"
  1635. if not code.include?(val)
  1636. errors = true
  1637. str = "Code ERROR: Var: " + var.name + "\tOrdinal: " + cell.ordinal.to_s + "\tArg: " + arg + "\tVal: " + val + "\n"
  1638. print str
  1639. if dump_file != ""
  1640. dump_file.write(str)
  1641. end
  1642. end
  1643. end
  1644. end
  1645. if not errors
  1646. puts "No errors found."
  1647. end
  1648. end
  1649.  
  1650.  
  1651. def getColumnList()
  1652. col_list = Array.new
  1653. $db.get_col_order_vector.each do |col_index|
  1654. col_list << $db.get_data_column(col_index).get_name
  1655. end
  1656.  
  1657. return col_list
  1658. end
  1659.  
  1660. def printAllNested(file)
  1661. columns = getColumnList()
  1662. columns.sort! # This is just so everything is the same across runs, regardless of column order
  1663. # Scan each column, getting a list of how many cells the cells of that
  1664. # contain and how much time the cells of that column fill
  1665.  
  1666. times = Hash.new
  1667.  
  1668. for outer_col in columns
  1669. collected_time = 0
  1670. for cell in outer_col.cells
  1671. collected_time += cell.offset - cell.onset
  1672. end
  1673. times[outer_col.name] = collected_time
  1674. end
  1675.  
  1676. # Now, we want to loop over the columns in the order of the amount of data
  1677. # that they take up.
  1678.  
  1679. end
  1680.  
  1681. def printCell(cell, file)
  1682.  
  1683. end
  1684.  
  1685. # This requires a column where the first cell in the column is the onset
  1686. # of the sync point, where 0 turns to 1 in the video. If you just want to
  1687. # match the first motion point with the first frame of video, then leave
  1688. # this argument blank.
  1689. def importDataSource(file, *sync_column)
  1690.  
  1691.  
  1692. end
  1693.  
  1694.  
  1695. ###################################################################################
  1696. # USER EDITABLE SECTION. PLEASE PLACE YOUR SCRIPT BETWEEN BEGIN AND END BELOW.
  1697. # #################################################################################
  1698.  
  1699. ## Check bout reliability, set the time tolerance as 100 ms
  1700.  
  1701. begin
  1702.  
  1703. #This line defines what the primary "et" and reliability "etrel" columns that
  1704. # you want to compare are. Onset and offset as labeled below tell the script that
  1705. #it does not have to check reliability for those arguments (because the reliability column
  1706. #is based off of the onsets and offsets of the primary column).
  1707. check_rel("et", "etrel", "onset", "offset")
  1708. puts "Checked Pick reliability DONE"
  1709.  
  1710. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement