Skip to content

Latest commit

 

History

History
229 lines (189 loc) · 10 KB

23-million-dollar-erisian.org

File metadata and controls

229 lines (189 loc) · 10 KB

23 Million Dollar Erisian

  ;;; 23-million-erisian.el --- Gnosis quantified with Neurosky.
  
  ;; Copyright (C) 2012 Jonathan Arkell
  
  ;; Author: Jonathan Arkell <[email protected]>
  ;; Created: 16 June 2012
  ;; Keywords: mindwave
  ;; Version 0.1 
  
  ;; This file is not part of GNU Emacs.
  ;; Released under the GPL     
  
  ;;; Commentary: 
  ;; Please see the org-file that this was generated from. 

* Changelog
  - From Mindwave Emacs
	- v 0.1.4 ::
	  - fix small provide error in 23-million-dollar-erisian
	- v 0.1.5
	  - Added extra info column in 23-million-dollar-erisian.  It doesn't have any use yet.
	  - remove raw hook from eeg display
	  - Raw serial connection, and raw eeg gathering finished.
	  - update mw-display/write-values so it uses with-current-buffer and inhibit-read-only
	  - mw-display now shows the total pakets recieved from the serial interface, bad packets, and sample rate
	- v 0.1.6
	  - Fix header line of main mindwave emacs
	  - Made mindwave-emacs byte-compileable
	  - mw-display shows a bit of information about the eeg
	  - mw display can show info from mw-info-catcher
	  - mw-info-catcher works
  - On its own

<<23mm-custom>>
<<23mm-commands>>
<<23mm-running-average>>
<<23mm-doinsertion>>
<<23mm-insert>>
<<23mm-timer>>
(provide '23-million-dollar-erisian)

The Point of the 23 million dollar erisian (6 Million, adjusted for Eris and Inflation) is to gather enough mindwave data to start to reason about your brian during varios hours, days of the week, and perhaps even days of the month or days–or months–of the year.

In order to do that, we will need data. Lots of data. But not too much data!

So the point of the 23 million dollar man is to store some of that data. Note that our grain size is rather large here (hour in a day). It is only because of the eegPower bands that we can really do this.

As an example, it shows how to maintain a running average.

Just as an aside, I renamed this file. 23-million-person is boring, so: 23-million-erisian. Why? because perhaps “23-million-man” is sexist.

Define a customization vars

  • store-in-org-file
  • tblname-of-data
(defgroup 23-million-erisian nil 
  "23 Million Man.  An stats collector for mindwave")

(defcustom 23-million-erisian/store-in-org-file "~/Dropbox/org/Brain.org"
  "Full file path of where to store the data."
  :group '23-million-erisian
  :type 'file)

(defcustom 23-million-erisian/tblname-of-data "23million"
  "Name of the table where data is to be stored."
  :type 'symbol
  :group '23-million-erisian)

Store hourly averages so statistical analysis can be performed on a per-hour, per day basis

(defcustom 23-million-erisian/ring-averages-per-insertion 2
  "Number of insertions to put into the table every time the ring fills up.
This is your effective resolution.  Here are some general approximations and timing:

val  time
1    30 seconds
2    1 minute
30   15 minutes
60   30 minutes
120  1 hour"
  :group '23-million-erisian)

(defvar 23-million-erisian/running-average-data nil
  "Data structure to hold the running average.
It is in the format of:
 (total-as-int . average-brain-ring-so-far)")

(defun 23-million-erisian/running-average-hook (average-brain-ring)
  "Takes an AVERAGE-BRAIN-RING, and then updates the minute average."
  (let ((total (+ (if 23-million-erisian/running-average-data
                      (car 23-million-erisian/running-average-data)
                    0)
                  1))
        (average (if 23-million-erisian/running-average-data
                     (cdr 23-million-erisian/running-average-data)
                   (mindwave/make-single-val-brain-ring 0))))
    (setq 23-million-erisian/running-average-data
          (cons total
                (mindwave/brain-ring-apply 'mindwave/safe-div
                                           (mindwave/brain-ring-apply '+  
                                                                     average
                                                                     average-brain-ring)
                                           (mindwave/make-single-val-brain-ring total))))
    (when (>= total 23-million-erisian/ring-averages-per-insertion)
      (23-million-erisian/do-insertion-into-file (cdr 23-million-erisian/running-average-data))
      (setq 23-million-erisian/running-average-data nil))))

Marking and Sensing

Mark interface just like datagather

Sensing

The sensing interface is used to sense when some kind of interesting neurological event has happened, and prompt the user (when available)

Table insertion

Unlike the shitty make-a-bunch-of-assumptions code for gather-into-org, this one will be better. Much better.

First, we will name a table and always write to that table. Then when we’re done writing, we’ll make a new line, with the comment #mindwave-last-pos, and store our position in a variable. This way we will be able to return to our pos, and verify that the position is right.

(defvar 23-million-erisian/tbl-buffer-pos nil)
(defconst 23-million-erisian/tbl-current-pos-marker "#mindwave-23million-pos")

(defun 23-million-erisian/do-insertion-into-file (data)
  "Inserts DATA into the 23-million-erisian table."
  (save-excursion
    (progn 
      (set-buffer (find-file-noselect 23-million-erisian/store-in-org-file))
      (23-million-erisian/find-buffer-pos)        
      (goto-char 23-million-erisian/tbl-buffer-pos)
      (when (not (string-equal (buffer-substring-no-properties (line-beginning-position) 
                                                               (line-end-position))
                               23-million-erisian/tbl-current-pos-marker))
        (error (concat "23-million-erisian: ARG, can't find the proper position to insert data! make sure you have '" 23-million-erisian/tbl-current-pos-marker "' at the bottom of your data table."))))
    (delete-region (line-beginning-position) 
                   (line-end-position))
    (23-million-erisian/write-running-average data)
    (setq 23-million-erisian/tbl-buffer-pos (line-beginning-position))
    (insert 23-million-erisian/tbl-current-pos-marker)
    (insert "\n"))) 

(defun 23-million-erisian/find-buffer-pos () 
  "find the current insert buffer position for the mindwave table.  
Start by opening the file if we have to."
  (save-excursion 
    (set-buffer (find-file-noselect 23-million-erisian/store-in-org-file))
    (goto-char (point-min))
    (if (re-search-forward (concat "^[ \t]*#\\+TBLNAME:[ \t]*" 
                                   23-million-erisian/tblname-of-data
                                   "[ \t]*$")
                           nil t)
        (progn 
          (goto-char (match-beginning 0))
          (if (re-search-forward 23-million-erisian/tbl-current-pos-marker nil t)
              (setq 23-million-erisian/tbl-buffer-pos (match-beginning 0))
            (error (concat "Cant find marker to insert data.  Make sure you have " 23-million-erisian/tbl-current-pos-marker " on your table."))))
      (error (concat "Can't find table data " 23-million-erisian/tblname-of-data)))))
  
(ert-deftest 23-million-erisian/find-buffer-pos () 
  ""
  (should (< 0 (23-million-erisian/find-buffer-pos)))
  (should-not (null 23-million-erisian/tbl-buffer-pos)))

Inserting the data

(defun 23-million-erisian/write-running-average (brain)
  "Writes the running average.  used as part of a run-timer"
  (let ((time (decode-time)))
                    ;   y     m     d     h     m    s      g     g    b      b     a     a    t      d     m     a     
    (insert (format "| %4s | %5s | %3s | %4s | %6s | %6s | %9s | %8s | %8s | %7s | %9s | %8s | %8s | %10s | %10s | %9s | %s | \n"
                    (nth 5 time)
                    (nth 4 time)
                    (nth 3 time)
                    (nth 2 time)
                    (nth 1 time)
                    (cdr (assoc 'poorSignalLevel brain))
                    (mindwave/access-in 'eegPower 'lowGamma brain)
                    (mindwave/access-in 'eegPower 'highGamma brain)
                    (mindwave/access-in 'eegPower 'lowBeta brain)
                    (mindwave/access-in 'eegPower 'highBeta brain)
                    (mindwave/access-in 'eegPower 'lowAlpha brain)
                    (mindwave/access-in 'eegPower 'highAlpha brain)
                    (mindwave/access-in 'eegPower 'theta brain)
                    (mindwave/access-in 'eegPower 'delta brain)
                    (mindwave/access-in 'eSense 'meditation brain)
                    (mindwave/access-in 'eSense 'attention brain)
                    23-million-erisian/mark))))  
(23-million-erisian/write-running-average (mindwave/make-single-val-brain-ring 10))
(mindwave/access-in 'eSense 'meditation  (mindwave/make-single-val-brain-ring 10))

Hook

;; note, I do this a lot, maybe it is time to abstract it properly in mindwave-emacs
(defun 23-million-erisian/start ()
  "Start recording the 23 million erisian."
  (interactive)
  (mindwave-get-buffer)
  (when (not (member '23-million-erisian/running-average-hook mindwave/brain-ring-full-hook))
    (add-hook 'mindwave/brain-ring-full-hook '23-million-erisian/running-average-hook)))

(defun 23-million-erisian/stop ()
  "Stop recording the 23 million erisian"
  (interactive)
  (remove-hook 'mindwave/brain-ring-full-hook '23-million-erisian/running-average-hook))