[yt-svn] commit/yt: 133 new changesets

Bitbucket commits-noreply at bitbucket.org
Tue Jun 26 21:20:16 PDT 2012


133 new commits in yt:


https://bitbucket.org/yt_analysis/yt/changeset/fe223e48779f/
changeset:   fe223e48779f
branch:      yt
user:        MatthewTurk
date:        2012-05-17 05:53:50
summary:     Intermediate commit for reorganizing and refactoring the Reason javascript.
affected #:  2 files

diff -r 3442625bb24f66b1cd15273f7feb708342bad20a -r fe223e48779f9ec93f187c790d0ec551fd8dd715 yt/gui/reason/html/js/functions.js
--- a/yt/gui/reason/html/js/functions.js
+++ b/yt/gui/reason/html/js/functions.js
@@ -87,9 +87,7 @@
 	        input_line.setValue(payload['value']);
             repl_input.locked = true;
         } else if (payload['type'] == 'log_entry') {
-	        var record = new logging_store.recordType(
-		        {record: payload['log_entry'] });
-	        logging_store.add(record, number_log_records++);
+            reason.log(payload['log_entry']);
             new_log = true;
         } else if (payload['type'] == 'widget') {
             var widget_type = payload['widget_type'];
@@ -110,7 +108,7 @@
         }
     });
     if (new_log == true){
-        viewport.get("status-region").getView().focusRow(number_log_records-1);
+        reason.log_scroll()
     }
     if (cell_resulted == true) {
         enable_input();


diff -r 3442625bb24f66b1cd15273f7feb708342bad20a -r fe223e48779f9ec93f187c790d0ec551fd8dd715 yt/gui/reason/html/js/reason.js
--- a/yt/gui/reason/html/js/reason.js
+++ b/yt/gui/reason/html/js/reason.js
@@ -29,29 +29,124 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ***********************************************************************/
 
+function Reason() {
+    if (typeof(console) != "undefined") {
+        console.log('Mitchell!\nPardon me! Mitchell!')
+    }
+    this.setup_viewport();
+    // Go ahead and create the TreePanel now so that we can use it below
+    // get a reference to the HTML element with id "hideit" and add a click listener to it 
+    Ext.get("hideit").on('click', function(){
+        // get a reference to the Panel that was created with id = 'west-panel' 
+	    var w = Ext.getCmp('west-panel');
+        // expand or collapse that Panel based on its collapsed property state
+        // need to make room for six sour cream burritos
+        w.collapsed ? w.expand() : w.collapse();
+    });
 
-var viewport;
-var widget_types = {}
-var widget_list = {}
+    /* Now we create our record store. */
+    this.logging_store = new Ext.data.Store({
+        fields: [{name:'record'}],
+        reader: new Ext.data.ArrayReader({}, [{name: 'record'}]),
+    });
 
+    this.number_log_records = 0;
+    this.number_images = 0;
+    this.cell_count = 0;
+    this.notebook = viewport.get("center-panel").get("notebook");
+    this.status_region = viewport.get("status-region");
+    
+}
+
+Reason.prototype.setup_viewport = function() {
+  this.viewport = new Ext.Viewport({
+        layout: 'border',
+        items: [
+		// lazily created panel (xtype:'panel' is default)
+            {
+                xtype: 'grid',
+                store: logging_store,
+                defaults: { width: 800 },
+                columns: [ {id:'record', 
+                    sortable: false,
+                    width:800} ],
+                autofill: true,
+                region: 'south',
+                id: "status-region",
+                cls: "status-logger",
+                split: true,
+                height: 100,
+                maxSize: 200,
+                collapsible: true,
+                title: 'Status',
+                margins: '0 0 0 0',
+            }, {
+                region: 'west',
+                id: 'west-panel', // see Ext.getCmp() below
+                title: 'Data Objects',
+                split: true,
+                width: 200,
+                minSize: 175,
+                maxSize: 400,
+                collapsible: true,
+                margins: '0 0 0 5',
+                layout: {
+                    type: 'anchor',
+                },
+                items: [{
+                        xtype: 'toolbar',
+                        items: [ main_menu ],
+                    },
+                    treePanel,
+                ]
+		  // in this instance the TabPanel is not wrapped by another panel
+		  // since no title is needed, this Panel is added directly
+		  // as a Container
+            },{
+                xtype: 'tabpanel',
+                region: 'center', 
+                id: 'center-panel',
+                deferredRender: false,
+                activeTab: 0,     
+                items: [{
+                        title: 'YT',
+                        id: 'notebook',
+                        layout: 'vbox',
+                        layoutConfig: {align:'stretch'},
+                        closable: false,
+                        autoScroll: false,
+                        iconCls: 'console',
+                        items: [CellInputContainer, OutputContainer]
+                    }, 
+                ]
+            }
+        ]
+    });
+}
+
+Reason.prototype.log = function(text) {
+    this.logging_store.add({record:text}, this.number_log_records++);
+}
+
+Reason.prototype.log_scroll = function() {
+    this.status_region.getView().focusRow(number_log_records-1);
+}
+
+var reason;
 var examine;
-var number_log_records = 0;
-var number_images = 0;
 
-var res;
-var cell_count = 0;
+/* This goes to the prototype so that it's shared across theoretical instances
+ * of the Reason class. */
+Reason.prototype.widget_types = {}
+Reason.prototype.widget_list = {}
 
-var handle_result = function(f, a) {
+Reason.prototype.handle_result = function(f, a) {
     if(a.status == false){
         Ext.Msg.alert("Error", "Something has gone wrong.");
         examine = {f: f, a: a};
         return;
     }
-    cell_finished(a.result);
-}
-
-var handle_payload = function(pp) {
-    cell_finished(pp);
+    this.cell_finished(a.result);
 }
 
 var repl_input = new Ext.FormPanel({
@@ -139,9 +234,6 @@
     items: []
 });
 
-var examine;
-var notebook;
-
 var treePanel = new Ext.tree.TreePanel({
     iconCls: 'nav',
     id: 'tree-panel',
@@ -217,12 +309,6 @@
     }
 });
 
-var status_panel;
-var logging_store = new Ext.data.Store({
-    fields: [{name:'record'}],
-    reader: new Ext.data.ArrayReader({}, [{name: 'record'}]),
-});
-
 var heartbeat_request = false;
 var task_runner = new Ext.util.TaskRunner();
 var heartbeat;
@@ -237,98 +323,10 @@
     // should ensure that stable state ids are set for stateful components in real apps.
     // it's a cold day for pontooning.
     Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
-
-    // Go ahead and create the TreePanel now so that we can use it below
-    viewport = new Ext.Viewport({
-        layout: 'border',
-        items: [
-		// lazily created panel (xtype:'panel' is default)
-            {
-                xtype: 'grid',
-                store: logging_store,
-                defaults: { width: 800 },
-                columns: [ {id:'record', 
-                    sortable: false,
-                    width:800} ],
-                autofill: true,
-                region: 'south',
-                id: "status-region",
-                cls: "status-logger",
-                split: true,
-                height: 100,
-                maxSize: 200,
-                collapsible: true,
-                title: 'Status',
-                margins: '0 0 0 0',
-            }, {
-                region: 'west',
-                id: 'west-panel', // see Ext.getCmp() below
-                title: 'Data Objects',
-                split: true,
-                width: 200,
-                minSize: 175,
-                maxSize: 400,
-                collapsible: true,
-                margins: '0 0 0 5',
-                layout: {
-                    type: 'anchor',
-                },
-                items: [{
-                        xtype: 'toolbar',
-                        items: [ main_menu ],
-                    },
-                    treePanel,
-                ]
-		  // in this instance the TabPanel is not wrapped by another panel
-		  // since no title is needed, this Panel is added directly
-		  // as a Container
-            },{
-                xtype: 'tabpanel',
-                region: 'center', 
-                id: 'center-panel',
-                deferredRender: false,
-                activeTab: 0,     
-                items: [{
-                        title: 'YT',
-                        id: 'notebook',
-                        layout: 'vbox',
-                        layoutConfig: {align:'stretch'},
-                        closable: false,
-                        autoScroll: false,
-                        iconCls: 'console',
-                        items: [CellInputContainer, OutputContainer]
-                    }, 
-                ]
-            }
-        ]
-    });
-
-// get a reference to the HTML element with id "hideit" and add a click listener to it 
-    if (typeof(console) != "undefined") {
-        console.log('Mitchell!\nPardon me! Mitchell!')
-    }
-    Ext.get("hideit").on('click', function(){
-// get a reference to the Panel that was created with id = 'west-panel' 
-	    var w = Ext.getCmp('west-panel');
-// expand or collapse that Panel based on its collapsed property state
-// need to make room for six sour cream burritos
-        w.collapsed ? w.expand() : w.collapse();
-    });
-    
-    notebook = viewport.get("center-panel").get("notebook");
-    status_panel = viewport.get("status-region").get("status-div");
-    
-    var record = new logging_store.recordType(
-        {record: 'Welcome to yt.'});
-    logging_store.add(record, number_log_records++);
-
-    var record = new logging_store.recordType(
-        {record: 'After entering a line of code in the YT Input field, press shift-enter to evaluate.' });
-    logging_store.add(record, number_log_records++);
-
-    var record = new logging_store.recordType(
-        {record: '4d3d3d3 engaged.' });
-    logging_store.add(record, number_log_records++);
+    reason = Reason()
+    reason.log('Welcome to yt.');
+    reason.log('After entering a line of code in the YT Input field, press shift-enter to evaluate.');
+    reason.log('4d3d3d3 engaged.');
 
     if (!Ext.state.Manager.get("reason_welcomed", false)) {
         Ext.MessageBox.alert("Reason v0.5",



https://bitbucket.org/yt_analysis/yt/changeset/0ae77580145d/
changeset:   0ae77580145d
branch:      yt
user:        MatthewTurk
date:        2012-05-17 06:20:12
summary:     Move heartbeat into reason object
affected #:  2 files

diff -r fe223e48779f9ec93f187c790d0ec551fd8dd715 -r 0ae77580145dd42266d6816741ffcf11f0101135 yt/gui/reason/html/js/functions.js
--- a/yt/gui/reason/html/js/functions.js
+++ b/yt/gui/reason/html/js/functions.js
@@ -29,18 +29,6 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ***********************************************************************/
 
-function enable_input() {
-    repl_input.body.removeClass("cell_waiting");
-    repl_input.get('input_line').setReadOnly(false);
-    repl_input.get("input_line").focus();
-    yt_rpc.ExtDirectParameterFileList.get_list_of_pfs({}, fill_tree);
-}
-
-function disable_input() {
-    repl_input.get('input_line').setReadOnly(true);
-    repl_input.body.addClass("cell_waiting");
-}
-
 function cell_finished(result) {
     var new_log = false;
     var cell_resulted = false;
@@ -48,8 +36,8 @@
     Ext.each(result, 
     function(payload, index) {
         if (payload['type'] == 'shutdown') {
-            task_runner.stop(heartbeat);
-            heartbeat_request = true;
+            reason.task_runner.stop(heartbeat);
+            reason.heartbeat_request = true;
             return;
         } else if (payload['type'] == 'cell_results') {
             text = "<pre>"+payload['output']+"</pre>";


diff -r fe223e48779f9ec93f187c790d0ec551fd8dd715 -r 0ae77580145dd42266d6816741ffcf11f0101135 yt/gui/reason/html/js/reason.js
--- a/yt/gui/reason/html/js/reason.js
+++ b/yt/gui/reason/html/js/reason.js
@@ -132,9 +132,6 @@
     this.status_region.getView().focusRow(number_log_records-1);
 }
 
-var reason;
-var examine;
-
 /* This goes to the prototype so that it's shared across theoretical instances
  * of the Reason class. */
 Reason.prototype.widget_types = {}
@@ -149,6 +146,37 @@
     this.cell_finished(a.result);
 }
 
+Reason.prototype.start_heartbeat = function() {
+    this.task_runner = new Ext.util.TaskRunner();
+    this.heartbeat_request = false;
+    this.number_heartbeats = 0;
+    this.heartbeat = {
+    run:
+      function(){ if (this.heartbeat_request == true) return; 
+        this.heartbeat_request = true;
+        yt_rpc.ExtDirectREPL.heartbeat(
+            {}, function(f, a) {
+            this.heartbeat_request = false;
+            if (f != null) {
+                handle_result(f, a);
+            }})},
+    interval: 250};
+
+    this.task_runner.start(heartbeat);
+}
+
+Reason.prototype.enable_input() {
+    repl_input.body.removeClass("cell_waiting");
+    repl_input.get('input_line').setReadOnly(false);
+    repl_input.get("input_line").focus();
+    yt_rpc.ExtDirectParameterFileList.get_list_of_pfs({}, fill_tree);
+}
+
+Reason.prototype.disable_input() {
+    repl_input.get('input_line').setReadOnly(true);
+    repl_input.body.addClass("cell_waiting");
+}
+                         
 var repl_input = new Ext.FormPanel({
     title: 'YT Input',
     url: 'push',
@@ -309,10 +337,8 @@
     }
 });
 
-var heartbeat_request = false;
-var task_runner = new Ext.util.TaskRunner();
-var heartbeat;
-
+var reason;
+var examine;
 
 Ext.onReady(function(){
     Ext.BLANK_IMAGE_URL = 'resources/resources/images/default/s.gif';
@@ -338,19 +364,5 @@
     }
 
     /* Set up the heartbeat */
-    var num = 0;
-    heartbeat = {
-    run:
-      function(){ if (heartbeat_request == true) return; 
-        heartbeat_request = true;
-        yt_rpc.ExtDirectREPL.heartbeat(
-            {}, function(f, a) {
-            heartbeat_request = false;
-            if (f != null) {
-                handle_result(f, a);
-            }})},
-    interval: 250};
-
-    task_runner.start(heartbeat);
-                         
+    reason.start_heartbeat();
 });



https://bitbucket.org/yt_analysis/yt/changeset/426eb572d235/
changeset:   426eb572d235
branch:      yt
user:        MatthewTurk
date:        2012-05-17 07:07:17
summary:     Still trying to figure out how to properly handle object instantiation in
ExtJS.
affected #:  1 file

diff -r 0ae77580145dd42266d6816741ffcf11f0101135 -r 426eb572d2354eec5efb2203426badc36bcf8b3c yt/gui/reason/html/js/reason.js
--- a/yt/gui/reason/html/js/reason.js
+++ b/yt/gui/reason/html/js/reason.js
@@ -29,7 +29,18 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ***********************************************************************/
 
-function Reason() {
+Ext.app.Module = function(config){
+    Ext.apply(this, config);
+    Ext.app.Module.superclass.constructor.call(this);
+    this.init();
+}
+
+Ext.extend(Ext.app.Module, Ext.util.Observable, {
+    init : Ext.emptyFn
+});
+
+Reason = new Ext.app.App({
+  init: function() {
     if (typeof(console) != "undefined") {
         console.log('Mitchell!\nPardon me! Mitchell!')
     }
@@ -50,16 +61,17 @@
         reader: new Ext.data.ArrayReader({}, [{name: 'record'}]),
     });
 
+    this.widget_types = {}
+    this.widget_list = {}
     this.number_log_records = 0;
     this.number_images = 0;
     this.cell_count = 0;
     this.notebook = viewport.get("center-panel").get("notebook");
     this.status_region = viewport.get("status-region");
-    
-}
+  },
 
-Reason.prototype.setup_viewport = function() {
-  this.viewport = new Ext.Viewport({
+  setup_viewport: function() {
+    this.viewport = new Ext.Viewport({
         layout: 'border',
         items: [
 		// lazily created panel (xtype:'panel' is default)
@@ -116,37 +128,32 @@
                         closable: false,
                         autoScroll: false,
                         iconCls: 'console',
-                        items: [CellInputContainer, OutputContainer]
+                        items: [InputContainer, OutputContainer]
                     }, 
                 ]
             }
         ]
     });
-}
+  },
 
-Reason.prototype.log = function(text) {
+  log : function(text) {
     this.logging_store.add({record:text}, this.number_log_records++);
-}
+  },
 
-Reason.prototype.log_scroll = function() {
+  log_scroll : function() {
     this.status_region.getView().focusRow(number_log_records-1);
-}
+  },
 
-/* This goes to the prototype so that it's shared across theoretical instances
- * of the Reason class. */
-Reason.prototype.widget_types = {}
-Reason.prototype.widget_list = {}
-
-Reason.prototype.handle_result = function(f, a) {
+  handle_result : function(f, a) {
     if(a.status == false){
         Ext.Msg.alert("Error", "Something has gone wrong.");
         examine = {f: f, a: a};
         return;
     }
     this.cell_finished(a.result);
-}
+  },
 
-Reason.prototype.start_heartbeat = function() {
+  start_heartbeat : function() {
     this.task_runner = new Ext.util.TaskRunner();
     this.heartbeat_request = false;
     this.number_heartbeats = 0;
@@ -163,95 +170,102 @@
     interval: 250};
 
     this.task_runner.start(heartbeat);
-}
+  },
 
-Reason.prototype.enable_input() {
+  enable_input : function() {
     repl_input.body.removeClass("cell_waiting");
     repl_input.get('input_line').setReadOnly(false);
     repl_input.get("input_line").focus();
     yt_rpc.ExtDirectParameterFileList.get_list_of_pfs({}, fill_tree);
-}
+  },
 
-Reason.prototype.disable_input() {
-    repl_input.get('input_line').setReadOnly(true);
-    repl_input.body.addClass("cell_waiting");
-}
-                         
-var repl_input = new Ext.FormPanel({
-    title: 'YT Input',
-    url: 'push',
-    flex: 0.2,
-    layout: 'fit',
-    padding: 5,
-    height: '100%',
-    flex: 1.0,
-    items: [{
-        id: 'input_line',
-        xtype: 'textarea',
-        width: '100%',
-        autoScroll: true,
-        name: 'line',
-        allowBlank: 'True',
-        bodyStyle: 'font-family: "monospace";',
-        listeners: {
-            specialkey: function(f, e){
-                if (e.getKey() == e.ENTER) {
-                    disable_input();
-                    yt_rpc.ExtDirectREPL.execute({
-                        code:repl_input.get('input_line').getValue()},
-                    handle_result);
-                }
-            },
-            afterrender: function(f, e){
-                //var input_line_drop_target_el = repl_input.get("input_line").el.dom;
-                var input_line_drop_target_el = repl_input.body.dom;
-
-                var input_line_drop_target = new Ext.dd.DropTarget(input_line_drop_target_el, {
-                    ddGroup     : 'pfDDgroup',
-                    notifyEnter : function(ddSource, e, data) {
-                        repl_input.body.stopFx();
-                        repl_input.body.highlight();
-                    },
-                    notifyDrop  : function(ddSource, e, data){
-
-                        var varname = data.node.attributes.objdata.varname;
-                        /* There is possibly a better way to do this, where it's also inserted correctly. */
-                        var line = repl_input.get("input_line");
-                        line.setValue(line.getValue() + varname);
-                        line.focus();
-                        return(true);
-                    }
-                });
-            },
-        },
-    },],
+  disable_input : function() {
+    this.InputCell.get('input_line').setReadOnly(true);
+    this.InputCell.body.addClass("cell_waiting");
+  },
 });
 
+Reason.Interpreter = function() { 
+    var interpreter = this;
+    this.execute = function() {
+        this.disable_input();
+        yt_rpc.ExtDirectREPL.execute({
+            code:this.InputForm.get('input_line').getValue()},
+        this.handle_result);
+    };
+    this.get_contents() {
+        return this.InputForm.get('input_line').getValue();
+    }
+    this.set_contents(contents, focus) {
+        this.InputForm.get('input_line').setValue(contents);
+        if (focus == true) {
+            this.InputForm.get('input_line').focus();
+        }
+    }
+    this.InputForm = new Ext.FormPanel({
+        title: 'YT Input',
+        url: 'push',
+        flex: 0.2,
+        layout: 'fit',
+        padding: 5,
+        height: '100%',
+        flex: 1.0,
+        items: [{
+            id: 'input_line',
+            xtype: 'textarea',
+            width: '100%',
+            autoScroll: true,
+            name: 'line',
+            allowBlank: 'True',
+            bodyStyle: 'font-family: "monospace";',
+            listeners: {
+                specialkey: function(f, e){
+                    if (e.getKey() == e.ENTER) {
+                        Reason.Interpreter.execute();
+                    }
+                },
+                afterrender: function(f, e){
+                    //var input_line_drop_target_el = repl_input.get("input_line").el.dom;
+                    var input_line_drop_target_el = repl_input.body.dom;
 
-var CellInputContainer = new Ext.Panel({
-    title: 'YT Input',
-    flex: 0.3,
-    layout: {type: 'hbox',
-             pack: 'start',
-             align: 'stretch',
-             },
-    items: [ repl_input,
-            { xtype: 'button',
-              width: 24,
-              height: 24,
-              iconCls: 'doubledownarrow',
-              tooltip: 'Execute Cell',
-              listeners: {
-                  click: function(f, e) {
-                    disable_input();
-                    yt_rpc.ExtDirectREPL.execute({
-                        code:repl_input.get('input_line').getValue()},
-                    handle_result);
-                  }
-              },
-            }
-           ]
-});
+                    var input_line_drop_target = new Ext.dd.DropTarget(input_line_drop_target_el, {
+                        ddGroup     : 'pfDDgroup',
+                        notifyEnter : function(ddSource, e, data) {
+                            repl_input.body.stopFx();
+                            repl_input.body.highlight();
+                        },
+                        notifyDrop  : function(ddSource, e, data){
+
+                            var varname = data.node.attributes.objdata.varname;
+                            /* There is possibly a better way to do this, where it's also inserted correctly. */
+                            var line = Reason.Interpreter.get_contents();
+                            Reason.interpreter.set_contents(line + varname, true);
+                            return(true);
+                        }
+                    });
+                },
+            },
+        },],
+    });
+    this.InputContainer = new Ext.Panel({
+        title: 'YT Input',
+        flex: 0.3,
+        layout: {type: 'hbox',
+                 pack: 'start',
+                 align: 'stretch',
+                 },
+        items: [ interpreter.InputForm,
+                { xtype: 'button',
+                  width: 24,
+                  height: 24,
+                  iconCls: 'doubledownarrow',
+                  tooltip: 'Execute Cell',
+                  listeners: {
+                      click: function(f, e) { interpreter.execute(); }
+                  },
+                }
+               ]
+    });
 
 
 var OutputContainer = new Ext.Panel({
@@ -262,7 +276,8 @@
     items: []
 });
 
-var treePanel = new Ext.tree.TreePanel({
+TreePanel = function(
+new Ext.tree.TreePanel({
     iconCls: 'nav',
     id: 'tree-panel',
     layout: 'anchor',



https://bitbucket.org/yt_analysis/yt/changeset/24372c00e442/
changeset:   24372c00e442
branch:      yt
user:        MatthewTurk
date:        2012-05-23 04:22:07
summary:     Merge
affected #:  2 files

diff -r 426eb572d2354eec5efb2203426badc36bcf8b3c -r 24372c00e4426902d93130e48e8802e446bad955 yt/data_objects/data_containers.py
--- a/yt/data_objects/data_containers.py
+++ b/yt/data_objects/data_containers.py
@@ -240,6 +240,8 @@
             pass
         elif isinstance(center, (types.ListType, types.TupleType, na.ndarray)):
             center = na.array(center)
+        elif center in ("c", "center"):
+            center = self.pf.domain_center
         elif center == ("max"): # is this dangerous for race conditions?
             center = self.pf.h.find_max("Density")[1]
         elif center.startswith("max_"):


diff -r 426eb572d2354eec5efb2203426badc36bcf8b3c -r 24372c00e4426902d93130e48e8802e446bad955 yt/utilities/parallel_tools/parallel_analysis_interface.py
--- a/yt/utilities/parallel_tools/parallel_analysis_interface.py
+++ b/yt/utilities/parallel_tools/parallel_analysis_interface.py
@@ -288,7 +288,7 @@
         if size is None:
             size = len(self.available_ranks)
         if len(self.available_ranks) < size:
-            print 'Not enough resources available'
+            print 'Not enough resources available', size, self.available_ranks
             raise RuntimeError
         if ranks is None:
             ranks = [self.available_ranks.pop(0) for i in range(size)]
@@ -315,6 +315,26 @@
         for wg in self.workgroups:
             self.free_workgroup(wg)
 
+    @classmethod
+    def from_sizes(cls, sizes):
+        sizes = ensure_list(sizes)
+        pool = cls()
+        rank = pool.comm.rank
+        for i,size in enumerate(sizes):
+            if iterable(size):
+                size, name = size
+            else:
+                name = "workgroup_%02i" % i
+            pool.add_workgroup(size, name = name)
+        for wg in pool.workgroups:
+            if rank in wg.ranks: workgroup = wg
+        return pool, workgroup
+
+    def __getitem__(self, key):
+        for wg in self.workgroups:
+            if wg.name == key: return wg
+        raise KeyError(key)
+
 class ResultsStorage(object):
     slots = ['result', 'result_id']
     result = None
@@ -517,24 +537,24 @@
         raise NotImplementedError
 
     @parallel_passthrough
-    def mpi_bcast(self, data):
+    def mpi_bcast(self, data, root = 0):
         # The second check below makes sure that we know how to communicate
         # this type of array. Otherwise, we'll pickle it.
         if isinstance(data, na.ndarray) and \
                 get_mpi_type(data.dtype) is not None:
-            if self.comm.rank == 0:
+            if self.comm.rank == root:
                 info = (data.shape, data.dtype)
             else:
                 info = ()
-            info = self.comm.bcast(info, root=0)
-            if self.comm.rank != 0:
+            info = self.comm.bcast(info, root=root)
+            if self.comm.rank != root:
                 data = na.empty(info[0], dtype=info[1])
             mpi_type = get_mpi_type(info[1])
-            self.comm.Bcast([data, mpi_type], root = 0)
+            self.comm.Bcast([data, mpi_type], root = root)
             return data
         else:
             # Use pickled methods.
-            data = self.comm.bcast(data, root = 0)
+            data = self.comm.bcast(data, root = root)
             return data
 
     def preload(self, grids, fields, io_handler):



https://bitbucket.org/yt_analysis/yt/changeset/8de765cd046a/
changeset:   8de765cd046a
branch:      yt
user:        MatthewTurk
date:        2012-05-29 23:14:42
summary:     First portion of an actual refactor to conform to MVC in ExtJS 4.1.

The layout for the notebook and the logging section currently work.  Once the
data object layout works, I will proceed to widgets and RPC.
affected #:  82 files
Diff too large to display.

https://bitbucket.org/yt_analysis/yt/changeset/be08682cd174/
changeset:   be08682cd174
branch:      yt
user:        MatthewTurk
date:        2012-05-29 23:31:38
summary:     Layout is a bit more functional with these changes.
affected #:  5 files

diff -r 8de765cd046a4c0d47161b73cdd86a26f0fc92ae -r be08682cd17465913db666ad543540ebe158737b yt/gui/reason/html/app.js
--- a/yt/gui/reason/html/app.js
+++ b/yt/gui/reason/html/app.js
@@ -54,9 +54,10 @@
                     collapsible: true,
                     title: 'Status',
                     margins: '0 0 0 0',
-               }, /*{
+               }, {
                     xtype: 'panel',
                     id: 'west-panel',
+                    region: 'west',
                     title: 'Data Objects',
                     split: true,
                     width: 200,
@@ -66,12 +67,7 @@
                     layout: {
                         type: 'anchor',
                     },
-                    items: [{
-                        xtype: 'reasontoolbar',
-                    }, {
-                        xtype: 'treepanel',
-                    }],
-              }, */ {
+              }, {
                 xtype: 'tabpanel',
                 region: 'center',
                 id: 'center-panel',


diff -r 8de765cd046a4c0d47161b73cdd86a26f0fc92ae -r be08682cd17465913db666ad543540ebe158737b yt/gui/reason/html/app/store/CellValues.js
--- a/yt/gui/reason/html/app/store/CellValues.js
+++ b/yt/gui/reason/html/app/store/CellValues.js
@@ -31,6 +31,7 @@
 
 Ext.define('Reason.store.CellValues', {
     extend: 'Ext.data.Store',
+    id: 'cellvalues',
     fields: ['input', 'output', 'raw_input', 'executiontime'],
     data: [{input: 'empty', output: 'alsoempty', raw_input:'moreempty',
     executiontime:0}],


diff -r 8de765cd046a4c0d47161b73cdd86a26f0fc92ae -r be08682cd17465913db666ad543540ebe158737b yt/gui/reason/html/app/view/CellInput.js
--- a/yt/gui/reason/html/app/view/CellInput.js
+++ b/yt/gui/reason/html/app/view/CellInput.js
@@ -48,12 +48,12 @@
                 items: [
                     {
                       xtype: 'textarea',
-                      id: 'inputLine',
+                      id: 'input_line',
                       autoScroll: true,
                       name: 'line',
                       width:'100%',
                       allowBlank: 'True',
-                      bodyStyle: 'font-family: "monospace";',
+                      fieldCls: 'inputLine',
                     },
                 ],
             }, {
@@ -62,5 +62,6 @@
                 tooltip: 'Execute Cell',
                 id: 'executecellbutton',
                 width: 24,
+                height: '100%',
             }],
 });


diff -r 8de765cd046a4c0d47161b73cdd86a26f0fc92ae -r be08682cd17465913db666ad543540ebe158737b yt/gui/reason/html/app/view/LoggingGrid.js
--- a/yt/gui/reason/html/app/view/LoggingGrid.js
+++ b/yt/gui/reason/html/app/view/LoggingGrid.js
@@ -34,5 +34,5 @@
     alias: 'widget.logginggrid',
     title: 'Logging Output',
     store: 'LogEntries',
-    columns: [ {header: 'Message', id:'record'} ],
+    columns: [ {header: 'Message', id:'record', width:'100%'} ],
 });


diff -r 8de765cd046a4c0d47161b73cdd86a26f0fc92ae -r be08682cd17465913db666ad543540ebe158737b yt/gui/reason/html/index.html
--- a/yt/gui/reason/html/index.html
+++ b/yt/gui/reason/html/index.html
@@ -9,8 +9,16 @@
 
     <!-- LIBS --><link rel="stylesheet" type="text/css" href="resources/extjs-4.1.0/resources/css/ext-all.css">
+    <link rel="stylesheet" type="text/css" href="resources/css/style.css">
+    <link rel="stylesheet" type="text/css" href="highlighter.css">
+
     <script type="text/javascript" src="resources/extjs-4.1.0/ext-all-debug.js"></script><script type="text/javascript" src="app.js"></script>
+
+    <!-- LEAFLET STUFF -->
+    <script type="text/javascript" src="resources/leaflet/leaflet.js"></script>
+    <link rel="stylesheet" href="resources/leaflet/leaflet.css" />
+
 </head><body></body>



https://bitbucket.org/yt_analysis/yt/changeset/252c77a54de5/
changeset:   252c77a54de5
branch:      yt
user:        MatthewTurk
date:        2012-05-29 23:40:09
summary:     Adding CSS from old version
affected #:  2 files

diff -r be08682cd17465913db666ad543540ebe158737b -r 252c77a54de5c427bfd1939cd93c591268bbcc3d yt/gui/reason/html/index.html
--- a/yt/gui/reason/html/index.html
+++ b/yt/gui/reason/html/index.html
@@ -8,7 +8,7 @@
     <link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Inconsolata"><!-- LIBS -->
-    <link rel="stylesheet" type="text/css" href="resources/extjs-4.1.0/resources/css/ext-all.css">
+    <link rel="stylesheet" type="text/css" href="resources/extjs-4.1.0/resources/css/ext-all-gray.css"><link rel="stylesheet" type="text/css" href="resources/css/style.css"><link rel="stylesheet" type="text/css" href="highlighter.css">
 


diff -r be08682cd17465913db666ad543540ebe158737b -r 252c77a54de5c427bfd1939cd93c591268bbcc3d yt/gui/reason/html/resources/css/style.css
--- /dev/null
+++ b/yt/gui/reason/html/resources/css/style.css
@@ -0,0 +1,65 @@
+
+html, body {
+    font:normal 12px verdana;
+    margin:0;
+    padding:0;
+    border:0 none;
+    overflow:hidden;
+    height:100%;
+}
+
+p {
+    margin:5px;
+}
+.pf_icon {
+    background-image:url(../images/blockdevice_tab.png) !important;
+}
+.data_object {
+    background-image:url(../images/3d_tab.png) !important;
+}
+.graph { 
+    background-image:url(../images/graph_tab.png) !important; //add ../images to tabs
+}
+.console { 
+    background-image:url(../images/console_tab.png) !important;
+}
+.doubleleftarrow { 
+    background-image:url(../images/double_left_sm.png) !important;
+}
+.singleleftarrow { 
+    background-image:url(../images/single_left_sm.png) !important;
+}
+.doubleuparrow { 
+    background-image:url(../images/double_up_sm.png) !important;
+}
+.singleuparrow { 
+    background-image:url(../images/single_up_sm.png) !important;
+}
+.doublerightarrow { 
+    background-image:url(../images/double_right_sm.png) !important;
+}
+.singlerightarrow { 
+    background-image:url(../images/single_right_sm.png) !important;
+}
+.doubledownarrow { 
+    background-image:url(../images/double_down_sm.png) !important;
+}
+.singledownarrow { 
+    background-image:url(../images/single_down_sm.png) !important;
+}
+.upload { 
+    background-image:url(../images/upload.png) !important;
+}
+
+.inputLine {
+    font-family: monospace;
+    font-size: 120%;
+}
+
+td.code {
+    padding-left: 20px;
+    font-family: monospace;
+}
+.cell_waiting {
+    background-color: #FF0000;
+}



https://bitbucket.org/yt_analysis/yt/changeset/1438e19d4fdf/
changeset:   1438e19d4fdf
branch:      yt
user:        MatthewTurk
date:        2012-05-30 16:01:03
summary:     Adding a splitter and getting cells to add correctly, with a first pass at a
template rendering system for input/output.
affected #:  6 files

diff -r 252c77a54de5c427bfd1939cd93c591268bbcc3d -r 1438e19d4fdf996bac192ccaddd547e1c3b1e743 yt/gui/reason/html/app.js
--- a/yt/gui/reason/html/app.js
+++ b/yt/gui/reason/html/app.js
@@ -31,6 +31,8 @@
 
 Ext.Loader.setConfig({enabled:true});
 
+var reason, examine;
+
 Ext.application({
     requires: ['Ext.container.Viewport',
                'Reason.view.LoggingGrid'],
@@ -39,6 +41,7 @@
     appFolder: 'app',
 
     launch: function() {
+        reason = this;
         Ext.create('Ext.container.Viewport', {
             layout: 'border',
             items: [


diff -r 252c77a54de5c427bfd1939cd93c591268bbcc3d -r 1438e19d4fdf996bac192ccaddd547e1c3b1e743 yt/gui/reason/html/app/controller/Notebook.js
--- a/yt/gui/reason/html/app/controller/Notebook.js
+++ b/yt/gui/reason/html/app/controller/Notebook.js
@@ -33,17 +33,21 @@
     extend: 'Ext.app.Controller',
     stores: [ 'CellValues' ],
     views: ['Notebook'],
+    refs: [
+        { ref: 'inputLine',
+          selector: '#input_line'
+        }
+    ],
 
     init: function() {
-        /*
         this.application.addListener({
-            'newcell': this.addCell,
-            'executecell': this.executeCell,
+            newcell: {fn: this.addCell, scope: this},
+            executecell: {fn: this.executeCell, scope: this},
         })
         this.control({
             '#executecellbutton': {
                 click: function(f, e) {
-                    this.executeCell(Ext.get('#input_line').getValue());
+                    this.executeCell(this.getInputLine().getValue());
                 }
             },
             '#inputline': {
@@ -54,16 +58,16 @@
                 },
             },
         });
-        */
         this.callParent(arguments);
     },
 
     addCell: function(cell) {
-        this.store.add({
+        examine = this;
+        this.getCellValuesStore().add({
             input: cell['input'],
             output: cell['output'],
             raw_input: cell['raw_input'],
-            executiontime: 0
+            executiontime: cell['executiontime'],
         });
     },
     executeCell: function(line) {


diff -r 252c77a54de5c427bfd1939cd93c591268bbcc3d -r 1438e19d4fdf996bac192ccaddd547e1c3b1e743 yt/gui/reason/html/app/store/CellValues.js
--- a/yt/gui/reason/html/app/store/CellValues.js
+++ b/yt/gui/reason/html/app/store/CellValues.js
@@ -33,7 +33,6 @@
     extend: 'Ext.data.Store',
     id: 'cellvalues',
     fields: ['input', 'output', 'raw_input', 'executiontime'],
-    data: [{input: 'empty', output: 'alsoempty', raw_input:'moreempty',
-    executiontime:0}],
+    data: [],
 });
 


diff -r 252c77a54de5c427bfd1939cd93c591268bbcc3d -r 1438e19d4fdf996bac192ccaddd547e1c3b1e743 yt/gui/reason/html/app/view/CellView.js
--- a/yt/gui/reason/html/app/view/CellView.js
+++ b/yt/gui/reason/html/app/view/CellView.js
@@ -29,6 +29,13 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ***********************************************************************/
 
+var cellDisplay = new Ext.XTemplate(
+    '<pre>{input}</pre>',
+    '<hr>',
+    '<pre>{output}</pre>'
+);
+
+
 Ext.define('Reason.view.CellView', {
     extend: 'Ext.grid.Panel',
     alias: 'widget.notebookcells',
@@ -36,16 +43,18 @@
     store: 'CellValues',
     autoscroll: true,
     flex: 0.7,
-    columns: [{header:'Execution Time', id: 'executiontime', width:'100%'}],
+    columns: [{header:'Execution Time', dataIndex: 'executiontime', width:'100%'}],
     features: [{
         ftype: 'rowbody',
         getAdditionalData: function(data, rowIndex, record, orig) {
             return {
-                rowBody: 'body',
-                rowBodyCls: 'something',
+                rowBody: cellDisplay.apply(data),
+                rowBodyCls: this.rowBodyCls,
                 rowBodyColspan: this.view.headerCt.getColumnCount(),
             };
         }
-    }]
+      }, {
+        ftype: 'rowwrap'
+      }],
 });
 


diff -r 252c77a54de5c427bfd1939cd93c591268bbcc3d -r 1438e19d4fdf996bac192ccaddd547e1c3b1e743 yt/gui/reason/html/app/view/Notebook.js
--- a/yt/gui/reason/html/app/view/Notebook.js
+++ b/yt/gui/reason/html/app/view/Notebook.js
@@ -46,6 +46,7 @@
     iconCls: 'console',
     items: [
         { xtype: 'notebookinput', },
+        { xtype: 'splitter' },
         { xtype: 'notebookcells', },
     ],
 });


diff -r 252c77a54de5c427bfd1939cd93c591268bbcc3d -r 1438e19d4fdf996bac192ccaddd547e1c3b1e743 yt/gui/reason/html/index.html
--- a/yt/gui/reason/html/index.html
+++ b/yt/gui/reason/html/index.html
@@ -8,7 +8,7 @@
     <link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Inconsolata"><!-- LIBS -->
-    <link rel="stylesheet" type="text/css" href="resources/extjs-4.1.0/resources/css/ext-all-gray.css">
+    <link rel="stylesheet" type="text/css" href="resources/extjs-4.1.0/resources/css/ext-all-slate.css"><link rel="stylesheet" type="text/css" href="resources/css/style.css"><link rel="stylesheet" type="text/css" href="highlighter.css">
 



https://bitbucket.org/yt_analysis/yt/changeset/07ce45146f90/
changeset:   07ce45146f90
branch:      yt
user:        MatthewTurk
date:        2012-05-30 16:29:33
summary:     ExtDirectREPL now enabled in its old state, now able to pass data back and
forth with server.
affected #:  4 files

diff -r 1438e19d4fdf996bac192ccaddd547e1c3b1e743 -r 07ce45146f909569158ad621e2f850c6bc7e2687 yt/gui/reason/extdirect_repl.py
--- a/yt/gui/reason/extdirect_repl.py
+++ b/yt/gui/reason/extdirect_repl.py
@@ -193,6 +193,11 @@
     matplotlib.rcParams["backend"] = "module://reason_agg"
     pylab.switch_backend("module://reason_agg")
 
+def static_file(fn):
+    def _static(self):
+        return open(os.path.join(local_dir, fn)).read()
+    return _static
+
 class ExtDirectREPL(ProgrammaticREPL, BottleDirectRouter):
     _skip_expose = ('index')
     my_name = "ExtDirectREPL"
@@ -215,15 +220,10 @@
         # than through metaclasses or other fancy decorating.
         preroute_table = dict(index = ("/", "GET"),
                               _help_html = ("/help.html", "GET"),
-                              _myapi = ("/resources/ext-repl-api.js", "GET"),
-                              _resources = ("/resources/:path#.+#", "GET"),
-                              _philogl = ("/philogl/:path#.+#", "GET"),
-                              _js = ("/js/:path#.+#", "GET"),
-                              _leaflet = ("/leaflet/:path#.+#", "GET"),
-                              _images = ("/images/:path#.+#", "GET"),
-                              _theme = ("/theme/:path#.+#", "GET"),
+                              _myapi = ("/ext-repl-api.js", "GET"),
                               _session_py = ("/session.py", "GET"),
                               _highlighter_css = ("/highlighter.css", "GET"),
+                              _app = ("/:path#.+#", "GET"),
                               )
         for v, args in preroute_table.items():
             preroute(args[0], method=args[1])(getattr(self, v))
@@ -262,13 +262,7 @@
         handler.setFormatter(formatter)
         ytLogger.addHandler(handler)
 
-
-    def index(self):
-        """Return an HTTP-based Read-Eval-Print-Loop terminal."""
-        # For now this doesn't work!  We will need to move to a better method
-        # for this.  It should use the package data command.
-        vals = open(os.path.join(local_dir, "html/index.html")).read()
-        return vals
+    index = static_file("html/index.html")
 
     def heartbeat(self):
         self.last_heartbeat = time.time()
@@ -308,9 +302,7 @@
         for t in threading.enumerate():
             print "Found a living thread:", t
 
-    def _help_html(self):
-        vals = open(os.path.join(local_dir, "html/help.html")).read()
-        return vals
+    _help_html = static_file("html/help.html")
 
     def _resources(self, path):
         pp = os.path.join(self.extjs_path, path)
@@ -333,22 +325,9 @@
             return
         return open(pp).read()
 
-    def _js(self, path):
-        pp = os.path.join(local_dir, "html", "js", path)
-        if not os.path.exists(pp):
-            response.status = 404
-            return
-        return open(pp).read()
-
-    def _leaflet(self, path):
-        pp = os.path.join(local_dir, "html", "leaflet", path)
-        if not os.path.exists(pp):
-            response.status = 404
-            return
-        return open(pp).read()
-
-    def _images(self, path):
-        pp = os.path.join(local_dir, "html", "images", path)
+    def _app(self, path):
+        pp = os.path.join(local_dir, "html", path)
+        mylog.warning("LOOKING FOR %s", pp)
         if not os.path.exists(pp):
             response.status = 404
             return
@@ -362,6 +341,7 @@
                     'code': code,
                     'hide': hide}
             self.execution_thread.queue.put(task)
+            return dict(status = True)
 
     def get_history(self):
         return self.executed_cell_texts[:]


diff -r 1438e19d4fdf996bac192ccaddd547e1c3b1e743 -r 07ce45146f909569158ad621e2f850c6bc7e2687 yt/gui/reason/html/app/controller/Notebook.js
--- a/yt/gui/reason/html/app/controller/Notebook.js
+++ b/yt/gui/reason/html/app/controller/Notebook.js
@@ -72,6 +72,11 @@
     },
     executeCell: function(line) {
         console.log("Asked to execute " + line);
+        yt_rpc.ExtDirectREPL.execute({code:line}, this.cellExecuted);
+    },
+    cellExecuted: function(result) {
+        console.log("Cell Executed!");
+        examine = result;
     }
 });
 


diff -r 1438e19d4fdf996bac192ccaddd547e1c3b1e743 -r 07ce45146f909569158ad621e2f850c6bc7e2687 yt/gui/reason/html/app/view/CellView.js
--- a/yt/gui/reason/html/app/view/CellView.js
+++ b/yt/gui/reason/html/app/view/CellView.js
@@ -35,7 +35,6 @@
     '<pre>{output}</pre>'
 );
 
-
 Ext.define('Reason.view.CellView', {
     extend: 'Ext.grid.Panel',
     alias: 'widget.notebookcells',


diff -r 1438e19d4fdf996bac192ccaddd547e1c3b1e743 -r 07ce45146f909569158ad621e2f850c6bc7e2687 yt/gui/reason/html/index.html
--- a/yt/gui/reason/html/index.html
+++ b/yt/gui/reason/html/index.html
@@ -14,6 +14,7 @@
 
     <script type="text/javascript" src="resources/extjs-4.1.0/ext-all-debug.js"></script><script type="text/javascript" src="app.js"></script>
+    <script type="text/javascript" src="ext-repl-api.js"></script><!-- LEAFLET STUFF --><script type="text/javascript" src="resources/leaflet/leaflet.js"></script>



https://bitbucket.org/yt_analysis/yt/changeset/12e0271dd7d3/
changeset:   12e0271dd7d3
branch:      yt
user:        MatthewTurk
date:        2012-05-30 17:10:53
summary:     Payload delivery is starting to work.
affected #:  6 files

diff -r 07ce45146f909569158ad621e2f850c6bc7e2687 -r 12e0271dd7d3d449e45e0d6fe82b37a01befd8ac yt/gui/reason/extdirect_repl.py
--- a/yt/gui/reason/extdirect_repl.py
+++ b/yt/gui/reason/extdirect_repl.py
@@ -139,7 +139,7 @@
             print "========================================================"
         if not hide:
             self.repl.payload_handler.add_payload(
-                {'type': 'cell_results',
+                {'type': 'cell',
                  'output': result,
                  'input': highlighter(code),
                  'raw_input': code},
@@ -251,7 +251,7 @@
         self.execution_thread.start()
 
     def exception_handler(self, exc):
-        result = {'type': 'cell_results',
+        result = {'type': 'cell',
                   'input': 'ERROR HANDLING IN REASON',
                   'output': traceback.format_exc()}
         return result
@@ -269,9 +269,13 @@
         if self.debug: print "### Heartbeat ... started: %s" % (time.ctime())
         for i in range(30):
             # Check for stop
+            if self.debug: print "    ###"
             if self.stopped: return {'type':'shutdown'} # No race condition
             if self.payload_handler.event.wait(1): # One second timeout
-                return self.payload_handler.deliver_payloads()
+                if self.debug: print "    ### Delivering payloads"
+                rv = self.payload_handler.deliver_payloads()
+                if self.debug: print "    ### Got back, returning"
+                return rv
         if self.debug: print "### Heartbeat ... finished: %s" % (time.ctime())
         return []
 
@@ -327,7 +331,6 @@
 
     def _app(self, path):
         pp = os.path.join(local_dir, "html", path)
-        mylog.warning("LOOKING FOR %s", pp)
         if not os.path.exists(pp):
             response.status = 404
             return
@@ -773,7 +776,7 @@
     def emit(self, record):
         msg = self.format(record)
         self.payload_handler.add_payload(
-            {'type':'log_entry',
+            {'type':'logentry',
              'log_entry':msg})
 
 if os.path.exists(os.path.expanduser("~/.yt/favicon.ico")):


diff -r 07ce45146f909569158ad621e2f850c6bc7e2687 -r 12e0271dd7d3d449e45e0d6fe82b37a01befd8ac yt/gui/reason/html/app.js
--- a/yt/gui/reason/html/app.js
+++ b/yt/gui/reason/html/app.js
@@ -86,5 +86,6 @@
         'Logging',
         /*'DataObjects',*/
         'Notebook',
+        'PayloadDirector',
     ],
 });


diff -r 07ce45146f909569158ad621e2f850c6bc7e2687 -r 12e0271dd7d3d449e45e0d6fe82b37a01befd8ac yt/gui/reason/html/app/controller/Logging.js
--- a/yt/gui/reason/html/app/controller/Logging.js
+++ b/yt/gui/reason/html/app/controller/Logging.js
@@ -33,4 +33,17 @@
     extend: 'Ext.app.Controller',
     stores: [ 'LogEntries' ],
     view: ['LoggingGrid'],
+
+    init: function() {
+        this.application.addListener({
+            payloadlogentry: {fn: this.addLogEntry, scope: this},
+        });
+    },
+
+    addLogEntry: function(payload) {
+        examine = payload;
+        this.getLogEntriesStore().add(
+            {record: payload['log_entry']}
+        );
+    },
 });


diff -r 07ce45146f909569158ad621e2f850c6bc7e2687 -r 12e0271dd7d3d449e45e0d6fe82b37a01befd8ac yt/gui/reason/html/app/controller/Notebook.js
--- a/yt/gui/reason/html/app/controller/Notebook.js
+++ b/yt/gui/reason/html/app/controller/Notebook.js
@@ -41,7 +41,7 @@
 
     init: function() {
         this.application.addListener({
-            newcell: {fn: this.addCell, scope: this},
+            payloadcell: {fn: this.addCell, scope: this},
             executecell: {fn: this.executeCell, scope: this},
         })
         this.control({
@@ -62,7 +62,6 @@
     },
 
     addCell: function(cell) {
-        examine = this;
         this.getCellValuesStore().add({
             input: cell['input'],
             output: cell['output'],
@@ -76,7 +75,6 @@
     },
     cellExecuted: function(result) {
         console.log("Cell Executed!");
-        examine = result;
     }
 });
 


diff -r 07ce45146f909569158ad621e2f850c6bc7e2687 -r 12e0271dd7d3d449e45e0d6fe82b37a01befd8ac yt/gui/reason/html/app/view/CellView.js
--- a/yt/gui/reason/html/app/view/CellView.js
+++ b/yt/gui/reason/html/app/view/CellView.js
@@ -42,7 +42,7 @@
     store: 'CellValues',
     autoscroll: true,
     flex: 0.7,
-    columns: [{header:'Execution Time', dataIndex: 'executiontime', width:'100%'}],
+    columns: [{header:'Execution Time', dataIndex: 'executiontime', flex:1}],
     features: [{
         ftype: 'rowbody',
         getAdditionalData: function(data, rowIndex, record, orig) {


diff -r 07ce45146f909569158ad621e2f850c6bc7e2687 -r 12e0271dd7d3d449e45e0d6fe82b37a01befd8ac yt/gui/reason/html/app/view/LoggingGrid.js
--- a/yt/gui/reason/html/app/view/LoggingGrid.js
+++ b/yt/gui/reason/html/app/view/LoggingGrid.js
@@ -34,5 +34,5 @@
     alias: 'widget.logginggrid',
     title: 'Logging Output',
     store: 'LogEntries',
-    columns: [ {header: 'Message', id:'record', width:'100%'} ],
+    columns: [ {header: 'Message', dataIndex:'record', flex:1} ],
 });



https://bitbucket.org/yt_analysis/yt/changeset/d2d510ab085b/
changeset:   d2d510ab085b
branch:      yt
user:        MatthewTurk
date:        2012-05-30 21:44:31
summary:     Read ExtJS from a zipfile, rather than from an extracted directory.
affected #:  3 files

diff -r 12e0271dd7d3d449e45e0d6fe82b37a01befd8ac -r d2d510ab085b4be5beebd1bcb8b863979a110d60 yt/gui/reason/extdirect_repl.py
--- a/yt/gui/reason/extdirect_repl.py
+++ b/yt/gui/reason/extdirect_repl.py
@@ -40,6 +40,7 @@
 import imp
 import threading
 import Queue
+import zipfile
 
 from yt.funcs import *
 from yt.utilities.logger import ytLogger, ufstring
@@ -209,9 +210,8 @@
 
     def __init__(self, base_extjs_path, locals=None):
         # First we do the standard initialization
-        self.extjs_path = os.path.join(base_extjs_path, "ext-resources")
-        self.extjs_theme_path = os.path.join(base_extjs_path, "ext-theme")
-        self.philogl_path = os.path.join(base_extjs_path, "PhiloGL")
+        self.extjs_file = zipfile.ZipFile(os.path.join(
+            base_extjs_path, "ext-4.1.0-gpl.zip"), 'r')
         ProgrammaticREPL.__init__(self, locals)
         # Now, since we want to only preroute functions we know about, and
         # since they have different arguments, and most of all because we only
@@ -223,6 +223,7 @@
                               _myapi = ("/ext-repl-api.js", "GET"),
                               _session_py = ("/session.py", "GET"),
                               _highlighter_css = ("/highlighter.css", "GET"),
+                              _extjs = ("/resources/extjs-4.1.0/:path#.+#", "GET"),
                               _app = ("/:path#.+#", "GET"),
                               )
         for v, args in preroute_table.items():
@@ -308,26 +309,14 @@
 
     _help_html = static_file("html/help.html")
 
-    def _resources(self, path):
-        pp = os.path.join(self.extjs_path, path)
-        if not os.path.exists(pp):
+    def _extjs(self, path):
+        pp = os.path.join("extjs-4.1.0", path)
+        try:
+            f = self.extjs_file.open(pp)
+        except KeyError:
             response.status = 404
             return
-        return open(pp).read()
-
-    def _philogl(self, path):
-        pp = os.path.join(self.philogl_path, path)
-        if not os.path.exists(pp):
-            response.status = 404
-            return
-        return open(pp).read()
-
-    def _theme(self, path):
-        pp = os.path.join(self.extjs_theme_path, path)
-        if not os.path.exists(pp):
-            response.status = 404
-            return
-        return open(pp).read()
+        return f.read()
 
     def _app(self, path):
         pp = os.path.join(local_dir, "html", path)


diff -r 12e0271dd7d3d449e45e0d6fe82b37a01befd8ac -r d2d510ab085b4be5beebd1bcb8b863979a110d60 yt/gui/reason/html/app/view/CellView.js
--- a/yt/gui/reason/html/app/view/CellView.js
+++ b/yt/gui/reason/html/app/view/CellView.js
@@ -43,6 +43,10 @@
     autoscroll: true,
     flex: 0.7,
     columns: [{header:'Execution Time', dataIndex: 'executiontime', flex:1}],
+    viewConfig: {
+        stripeRows: false,
+        disableSelection: true,
+    },
     features: [{
         ftype: 'rowbody',
         getAdditionalData: function(data, rowIndex, record, orig) {


diff -r 12e0271dd7d3d449e45e0d6fe82b37a01befd8ac -r d2d510ab085b4be5beebd1bcb8b863979a110d60 yt/gui/reason/html/index.html
--- a/yt/gui/reason/html/index.html
+++ b/yt/gui/reason/html/index.html
@@ -8,7 +8,7 @@
     <link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Inconsolata"><!-- LIBS -->
-    <link rel="stylesheet" type="text/css" href="resources/extjs-4.1.0/resources/css/ext-all-slate.css">
+    <link rel="stylesheet" type="text/css" href="resources/extjs-4.1.0/resources/css/ext-all-gray.css"><link rel="stylesheet" type="text/css" href="resources/css/style.css"><link rel="stylesheet" type="text/css" href="highlighter.css">
 



https://bitbucket.org/yt_analysis/yt/changeset/b9b74efbfce2/
changeset:   b9b74efbfce2
branch:      yt
user:        MatthewTurk
date:        2012-05-30 23:07:51
summary:     Add help file, more styling, turn on and off input as necessary.
affected #:  6 files

diff -r d2d510ab085b4be5beebd1bcb8b863979a110d60 -r b9b74efbfce2762b66be58acb42af3565f938a14 yt/gui/reason/html/app.js
--- a/yt/gui/reason/html/app.js
+++ b/yt/gui/reason/html/app.js
@@ -75,9 +75,14 @@
                 region: 'center',
                 id: 'center-panel',
                 activeTab: 0,
-                items: [{
-                    xtype: 'ytnotebook'
-                }]
+                items: [
+                { xtype: 'panel',
+                  title: 'Welcome!',
+                  closeable: true,
+                  autoLoad: 'help.html',
+                },
+                { xtype: 'ytnotebook' },
+                ]
               }
             ]
         });


diff -r d2d510ab085b4be5beebd1bcb8b863979a110d60 -r b9b74efbfce2762b66be58acb42af3565f938a14 yt/gui/reason/html/app/controller/Notebook.js
--- a/yt/gui/reason/html/app/controller/Notebook.js
+++ b/yt/gui/reason/html/app/controller/Notebook.js
@@ -32,17 +32,27 @@
 Ext.define('Reason.controller.Notebook', {
     extend: 'Ext.app.Controller',
     stores: [ 'CellValues' ],
-    views: ['Notebook'],
+    views: ['Notebook', 'CellView'],
     refs: [
         { ref: 'inputLine',
-          selector: '#input_line'
-        }
+          selector: '#inputline'
+        },
+        { ref: 'cellDisplay',
+          selector: 'notebookcells#cells',
+          xtype: 'notebookcells',
+          autoCreate: true,
+          itemId: 'cells',
+        },
     ],
 
     init: function() {
         this.application.addListener({
             payloadcell: {fn: this.addCell, scope: this},
             executecell: {fn: this.executeCell, scope: this},
+            wipeinput:   {fn: this.wipeInputLine, scope: this},
+            blockinput:  {fn: this.blockInput, scope: this},
+            allowinput:  {fn: this.allowInput, scope: this},
+            scrolltobottom: {fn: this.scrollToBottom, scope: this},
         })
         this.control({
             '#executecellbutton': {
@@ -51,8 +61,8 @@
                 }
             },
             '#inputline': {
-                specialkey: function(ed, field, e, opts){
-                    if (e.getKey() == e.ENTER) {
+                specialkey: function(field, e, opts){
+                    if (e.shiftKey && e.getKey() == e.ENTER) {
                         this.executeCell(field.getValue());
                     }
                 },
@@ -62,19 +72,50 @@
     },
 
     addCell: function(cell) {
+        this.application.fireEvent("wipeinput");
+        this.application.fireEvent("allowinput");
         this.getCellValuesStore().add({
             input: cell['input'],
             output: cell['output'],
             raw_input: cell['raw_input'],
             executiontime: cell['executiontime'],
         });
+        this.application.fireEvent("scrolltobottom");
     },
     executeCell: function(line) {
+        this.application.fireEvent("blockinput");
         console.log("Asked to execute " + line);
         yt_rpc.ExtDirectREPL.execute({code:line}, this.cellExecuted);
     },
+
+    scrollToBottom: function() {
+        var i = this.getCellValuesStore().getCount();
+        console.log("Scrolling to bottom: " + i);
+        this.getCellDisplay().getView().focusRow(i-1);
+        examine = this.getCellDisplay();
+    },
+    
+    wipeInputLine: function() {
+        this.getInputLine().setValue("");
+    },
+
+    blockInput: function() {
+        this.getInputLine().addClass("cell_waiting");
+        this.getInputLine().setReadOnly(true);
+    },
+
+    allowInput: function() {
+        this.getInputLine().removeCls("cell_waiting");
+        this.getInputLine().setReadOnly(false);
+        /*yt_rpc.ExtDirectParameterFileList.get_list_of_pfs({}, 
+            function(f, a) {
+                if (f == null) { alert("Error!"); return; }
+                this.application.fireEvent("newparameterfiles", f);
+        });*/
+    },
+
     cellExecuted: function(result) {
         console.log("Cell Executed!");
-    }
+    },
 });
 


diff -r d2d510ab085b4be5beebd1bcb8b863979a110d60 -r b9b74efbfce2762b66be58acb42af3565f938a14 yt/gui/reason/html/app/view/CellInput.js
--- a/yt/gui/reason/html/app/view/CellInput.js
+++ b/yt/gui/reason/html/app/view/CellInput.js
@@ -48,7 +48,7 @@
                 items: [
                     {
                       xtype: 'textarea',
-                      id: 'input_line',
+                      id: 'inputline',
                       autoScroll: true,
                       name: 'line',
                       width:'100%',


diff -r d2d510ab085b4be5beebd1bcb8b863979a110d60 -r b9b74efbfce2762b66be58acb42af3565f938a14 yt/gui/reason/html/app/view/CellView.js
--- a/yt/gui/reason/html/app/view/CellView.js
+++ b/yt/gui/reason/html/app/view/CellView.js
@@ -30,9 +30,12 @@
 ***********************************************************************/
 
 var cellDisplay = new Ext.XTemplate(
-    '<pre>{input}</pre>',
+    '<b>Input:</b><br/><br/>',
+    '{input}',
+    '<br/><br/>',
     '<hr>',
-    '<pre>{output}</pre>'
+    '<b>Output:</b><br/><br/>',
+    '<pre>{output}</pre><br/><br/>'
 );
 
 Ext.define('Reason.view.CellView', {
@@ -40,19 +43,21 @@
     alias: 'widget.notebookcells',
     title: 'Cells',
     store: 'CellValues',
+    itemId: 'cells',
     autoscroll: true,
     flex: 0.7,
     columns: [{header:'Execution Time', dataIndex: 'executiontime', flex:1}],
     viewConfig: {
         stripeRows: false,
         disableSelection: true,
+        trackOver: false,
     },
     features: [{
         ftype: 'rowbody',
         getAdditionalData: function(data, rowIndex, record, orig) {
             return {
                 rowBody: cellDisplay.apply(data),
-                rowBodyCls: this.rowBodyCls,
+                rowBodyCls: 'codeview',
                 rowBodyColspan: this.view.headerCt.getColumnCount(),
             };
         }


diff -r d2d510ab085b4be5beebd1bcb8b863979a110d60 -r b9b74efbfce2762b66be58acb42af3565f938a14 yt/gui/reason/html/index.html
--- a/yt/gui/reason/html/index.html
+++ b/yt/gui/reason/html/index.html
@@ -1,6 +1,6 @@
 <html><head>
-  <title>Reason YT GUI</title>
+  <title>Reason: yt GUI</title><!-- FONTS --><!-- These will get pulled from Google, but Google might not be accessible.


diff -r d2d510ab085b4be5beebd1bcb8b863979a110d60 -r b9b74efbfce2762b66be58acb42af3565f938a14 yt/gui/reason/html/resources/css/style.css
--- a/yt/gui/reason/html/resources/css/style.css
+++ b/yt/gui/reason/html/resources/css/style.css
@@ -1,12 +1,3 @@
-
-html, body {
-    font:normal 12px verdana;
-    margin:0;
-    padding:0;
-    border:0 none;
-    overflow:hidden;
-    height:100%;
-}
 
 p {
     margin:5px;
@@ -56,10 +47,12 @@
     font-size: 120%;
 }
 
-td.code {
+tr.codeview td, tr.codeview pre {
     padding-left: 20px;
     font-family: monospace;
+    font-size: 12px;
 }
+
 .cell_waiting {
     background-color: #FF0000;
 }



https://bitbucket.org/yt_analysis/yt/changeset/c1753def7b76/
changeset:   c1753def7b76
branch:      yt
user:        MatthewTurk
date:        2012-05-31 00:26:47
summary:     First part of the parameter file / data object passing back and forth from the
server.  Also forgot to add the payload director in a previous commit.
affected #:  8 files

diff -r b9b74efbfce2762b66be58acb42af3565f938a14 -r c1753def7b76ff2925955f1e499aee765214a8a0 yt/gui/reason/extdirect_repl.py
--- a/yt/gui/reason/extdirect_repl.py
+++ b/yt/gui/reason/extdirect_repl.py
@@ -743,8 +743,10 @@
                     except ReferenceError:
                         continue
                     objs.append(dict(name=name, type=obj._type_name,
+                                     filename = '', field_list = [],
                                      varname = "%s.h.objects[%s]" % (pf_varname, i)))
-            rv.append( dict(name = str(pf), objects = objs, filename=fn,
+            rv.append( dict(name = str(pf), children = objs, filename=fn,
+                            type = "parameter_file",
                             varname = pf_varname, field_list = fields) )
         return rv
 


diff -r b9b74efbfce2762b66be58acb42af3565f938a14 -r c1753def7b76ff2925955f1e499aee765214a8a0 yt/gui/reason/html/app.js
--- a/yt/gui/reason/html/app.js
+++ b/yt/gui/reason/html/app.js
@@ -35,7 +35,8 @@
 
 Ext.application({
     requires: ['Ext.container.Viewport',
-               'Reason.view.LoggingGrid'],
+               'Reason.view.LoggingGrid',
+               'Reason.view.DataObjectTree'],
     name: 'Reason',
 
     appFolder: 'app',
@@ -58,7 +59,7 @@
                     title: 'Status',
                     margins: '0 0 0 0',
                }, {
-                    xtype: 'panel',
+                    xtype: 'dataobjecttree',
                     id: 'west-panel',
                     region: 'west',
                     title: 'Data Objects',
@@ -89,7 +90,7 @@
     },
     controllers : [
         'Logging',
-        /*'DataObjects',*/
+        'DataObjects',
         'Notebook',
         'PayloadDirector',
     ],


diff -r b9b74efbfce2762b66be58acb42af3565f938a14 -r c1753def7b76ff2925955f1e499aee765214a8a0 yt/gui/reason/html/app/controller/DataObjects.js
--- /dev/null
+++ b/yt/gui/reason/html/app/controller/DataObjects.js
@@ -0,0 +1,81 @@
+/**********************************************************************
+Data object controller for Reason
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define('Reason.controller.DataObjects', {
+    extend: 'Ext.app.Controller',
+    stores: [ 'DataObjects' ],
+    view: ['DataObjectTree'],
+    refs: [
+        { ref: 'dataObjectTree',
+          selector: 'dataobjecttree#dataobjects',
+          xtype: 'dataobjecttree',
+          itemId: 'dataobjects',
+          autoCreate: true,
+        },
+    ],
+
+
+    init: function() {
+        this.application.addListener({
+           newdataobjects : {fn: this.refreshDataObjects, scope: this},
+        });
+        this.callParent(arguments);
+    },
+
+    refreshDataObjects: function(objs) {
+        console.log("Refreshing data objects");
+        var view = this.getDataObjectTree();
+        var store = this.getDataObjectsStore();
+        store.removeAll();
+        store.setRootNode({text: '', leaf: false, expanded: true});
+        var root = store.getRootNode();
+        var pf;
+        Ext.each(objs, function(o, i, os) {
+            console.log("Appending " + o['name']);
+            pf = root.appendChild({
+                text: o['name'],
+                objdata: o,
+                leaf: false,
+                expanded: true,
+                iconCls: 'pf_icon'
+            });
+            Ext.each(o['children'], function(c, ci, cs) {
+                console.log("    Appending " + c['name']);
+                pf.appendChild({text: c['name'],
+                                objdata: c,
+                                leaf: true,
+                                iconcls: 'data_obj'});
+
+            });
+        });
+    },
+});
+


diff -r b9b74efbfce2762b66be58acb42af3565f938a14 -r c1753def7b76ff2925955f1e499aee765214a8a0 yt/gui/reason/html/app/controller/Notebook.js
--- a/yt/gui/reason/html/app/controller/Notebook.js
+++ b/yt/gui/reason/html/app/controller/Notebook.js
@@ -92,7 +92,6 @@
         var i = this.getCellValuesStore().getCount();
         console.log("Scrolling to bottom: " + i);
         this.getCellDisplay().getView().focusRow(i-1);
-        examine = this.getCellDisplay();
     },
     
     wipeInputLine: function() {
@@ -107,11 +106,13 @@
     allowInput: function() {
         this.getInputLine().removeCls("cell_waiting");
         this.getInputLine().setReadOnly(false);
-        /*yt_rpc.ExtDirectParameterFileList.get_list_of_pfs({}, 
+        console.log("Calling FileList");
+        var application = this.application;
+        yt_rpc.ExtDirectParameterFileList.get_list_of_pfs({}, 
             function(f, a) {
                 if (f == null) { alert("Error!"); return; }
-                this.application.fireEvent("newparameterfiles", f);
-        });*/
+                application.fireEvent("newdataobjects", f);
+        });
     },
 
     cellExecuted: function(result) {


diff -r b9b74efbfce2762b66be58acb42af3565f938a14 -r c1753def7b76ff2925955f1e499aee765214a8a0 yt/gui/reason/html/app/controller/PayloadDirector.js
--- /dev/null
+++ b/yt/gui/reason/html/app/controller/PayloadDirector.js
@@ -0,0 +1,68 @@
+/**********************************************************************
+The Payload handling facility for Reason
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+var heartbeatRequest = false;
+
+Ext.define('Reason.controller.PayloadDirector', {
+    extend: 'Ext.app.Controller',
+
+    init: function() {
+        this.application.addListener({
+            payloadreceived: {fn: this.handlePayload, scope: this},
+        })
+        /* We also use this as our heartbeat */
+        this.taskRunner = new Ext.util.TaskRunner();
+        heartbeatRequest = false;
+        this.heartbeat = this.taskRunner.start(
+            {run: this.heartbeatCall,
+             interval: 250});
+        this.callParent(arguments);
+    },
+    handlePayload: function(payload) {
+        this.application.fireEvent('payload' + payload['type'], payload);
+    },
+    heartbeatCall: function() {
+        if (heartbeatRequest == true) return;
+        heartbeatRequest = true;
+        yt_rpc.ExtDirectREPL.heartbeat(
+            {}, function(f, a) {
+                heartbeatRequest = false;
+                if (f != null) { 
+                    Ext.each(f, function(payload, index) {
+                            reason.fireEvent("payloadreceived", payload);
+                    });
+                }
+                return true;
+            }
+        );
+    }
+});
+


diff -r b9b74efbfce2762b66be58acb42af3565f938a14 -r c1753def7b76ff2925955f1e499aee765214a8a0 yt/gui/reason/html/app/store/DataObjects.js
--- /dev/null
+++ b/yt/gui/reason/html/app/store/DataObjects.js
@@ -0,0 +1,37 @@
+/**********************************************************************
+Logging entry store for Reason
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define('Reason.store.DataObjects', {
+    extend: 'Ext.data.TreeStore',
+    fields: ['name', 'type', 'filename', 'field_list', 'varname'],
+    data: [],
+});
+


diff -r b9b74efbfce2762b66be58acb42af3565f938a14 -r c1753def7b76ff2925955f1e499aee765214a8a0 yt/gui/reason/html/app/view/DataObjectTree.js
--- /dev/null
+++ b/yt/gui/reason/html/app/view/DataObjectTree.js
@@ -0,0 +1,46 @@
+/**********************************************************************
+Data Object Tree for Reason
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define('Reason.view.DataObjectTree', {
+    extend: 'Ext.tree.Panel',
+    alias: 'widget.dataobjecttree',
+    title: 'Data Objects',
+    store: 'DataObjects',
+    itemId: 'dataobjects',
+    rootVisible: false,
+    iconCls: 'nav',
+    root: {
+        expanded: true,
+        text: '',
+        leaf: false,
+    },
+});
+


diff -r b9b74efbfce2762b66be58acb42af3565f938a14 -r c1753def7b76ff2925955f1e499aee765214a8a0 yt/gui/reason/html/index.html
--- a/yt/gui/reason/html/index.html
+++ b/yt/gui/reason/html/index.html
@@ -15,6 +15,7 @@
     <script type="text/javascript" src="resources/extjs-4.1.0/ext-all-debug.js"></script><script type="text/javascript" src="app.js"></script><script type="text/javascript" src="ext-repl-api.js"></script>
+    <script type="text/javascript" src="resources/ext-pflist-api.js"></script><!-- LEAFLET STUFF --><script type="text/javascript" src="resources/leaflet/leaflet.js"></script>



https://bitbucket.org/yt_analysis/yt/changeset/47094c9542e2/
changeset:   47094c9542e2
branch:      yt
user:        MatthewTurk
date:        2012-05-31 03:39:24
summary:     A minor modification to get treecolumns in the data object tree.
affected #:  1 file

diff -r c1753def7b76ff2925955f1e499aee765214a8a0 -r 47094c9542e2ad48b54789108882ddcf8faf9285 yt/gui/reason/html/app/view/DataObjectTree.js
--- a/yt/gui/reason/html/app/view/DataObjectTree.js
+++ b/yt/gui/reason/html/app/view/DataObjectTree.js
@@ -42,5 +42,11 @@
         text: '',
         leaf: false,
     },
+    columns: [{
+        xtype: 'treecolumn',
+        text: 'Name',
+        sortable: false,
+        dataIndex: 'text',
+    }],
 });
 



https://bitbucket.org/yt_analysis/yt/changeset/62ef095a290c/
changeset:   62ef095a290c
branch:      yt
user:        MatthewTurk
date:        2012-05-31 03:42:31
summary:     Renaming all the widget stuff to live in controllers.widgets
affected #:  16 files

diff -r 47094c9542e2ad48b54789108882ddcf8faf9285 -r 62ef095a290cc6041ee9cb44794535b8884b2e0f yt/gui/reason/html/app/controller/widgets/GridDataViewer.js
--- /dev/null
+++ b/yt/gui/reason/html/app/controller/widgets/GridDataViewer.js
@@ -0,0 +1,146 @@
+/**********************************************************************
+The Plot Window Widget
+
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+// shim layer with setTimeout fallback
+var WidgetGridDataViewer = function(python_varname, widget_data) {
+    this.id = python_varname;
+    this.widget_data = widget_data;
+    store = new Ext.data.ArrayStore({
+        fields: [
+           {name: 'grid_id', type:'int'},
+           {name: 'level', type:'int'},
+           {name: 'left_edge_x', type: 'float'},
+           {name: 'left_edge_y', type: 'float'},
+           {name: 'left_edge_z', type: 'float'},
+           {name: 'right_edge_x', type: 'float'},
+           {name: 'right_edge_y', type: 'float'},
+           {name: 'right_edge_z', type: 'float'},
+           {name: 'dim_x', type: 'int'},
+           {name: 'dim_y', type: 'int'},
+           {name: 'dim_z', type: 'int'},
+           {name: 'cells', type: 'int'},
+        ]
+    });
+    store.loadData(widget_data['gridvals']);
+    examine = widget_data;
+
+    viewport.get("center-panel").add(
+        {
+            xtype: 'panel',
+            id: "gg_" + python_varname,
+            title: "Grid Data Viewer",
+            iconCls: 'graph',
+            autoScroll: true,
+            layout:'vbox',
+            layoutConfig: {align: 'stretch', pack: 'start'},
+            closable: true,
+            items: [ {
+                       xtype: 'grid',
+                       store: store,
+                       columns: [
+                            {
+                                id: 'grid_id',
+                                header: 'Grid ID',
+                                width: 100,
+                                dataIndex: 'grid_id',
+                                sortable: true,
+                            }, {
+                                id: 'left_edge_x',
+                                header: 'Left Edge x',
+                                width: 100,
+                                dataIndex: 'left_edge_x',
+                                sortable: true,
+                            }, {
+                                id: 'left_edge_y',
+                                header: 'Left Edge y',
+                                width: 100,
+                                dataIndex: 'left_edge_y',
+                                sortable: true,
+                            }, {
+                                id: 'left_edge_z',
+                                header: 'Left Edge z',
+                                width: 100,
+                                dataIndex: 'left_edge_z',
+                                sortable: true,
+                            }, {
+                                id: 'right_edge_x',
+                                header: 'Right Edge x',
+                                width: 100,
+                                dataIndex: 'right_edge_x',
+                                sortable: true,
+                            }, {
+                                id: 'right_edge_y',
+                                header: 'Right Edge y',
+                                width: 100,
+                                dataIndex: 'right_edge_y',
+                                sortable: true,
+                            }, {
+                                id: 'right_edge_z',
+                                header: 'Right Edge z',
+                                width: 100,
+                                dataIndex: 'right_edge_z',
+                                sortable: true,
+                            }, {
+                                id: 'dim_x',
+                                header: 'DimX',
+                                width: 100,
+                                dataIndex: 'dim_x',
+                                sortable: true,
+                            }, {
+                                id: 'dim_y',
+                                header: 'DimY',
+                                width: 100,
+                                dataIndex: 'dim_y',
+                                sortable: true,
+                            }, {
+                                id: 'dim_z',
+                                header: 'DimZ',
+                                width: 100,
+                                dataIndex: 'dim_z',
+                                sortable: true,
+                            }, {
+                                id: 'cells',
+                                header: 'Cells',
+                                width: 100,
+                                dataIndex: 'cells',
+                                sortable: true,
+                            },
+                       ],
+                      flex: 1,
+                      }
+                   ],
+
+        }
+    );
+
+    viewport.get("center-panel").activate("gg_" + this.id);
+    viewport.doLayout();
+    this.panel = viewport.get("center-panel").get("gg_" + python_varname);
+    this.panel.doLayout();
+
+    this.accept_results = function(payload) { }
+}
+
+widget_types['grid_data'] = WidgetGridDataViewer;


diff -r 47094c9542e2ad48b54789108882ddcf8faf9285 -r 62ef095a290cc6041ee9cb44794535b8884b2e0f yt/gui/reason/html/app/controller/widgets/GridViewer.js
--- /dev/null
+++ b/yt/gui/reason/html/app/controller/widgets/GridViewer.js
@@ -0,0 +1,211 @@
+/**********************************************************************
+The Plot Window Widget
+
+Author: Samuel Skillman <samskillman at gmail.com>
+Affiliation: University of Colorado at Boulder
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+// shim layer with setTimeout fallback
+window.requestAnimFrame = (function(){
+    return  window.requestAnimationFrame       || 
+        window.webkitRequestAnimationFrame || 
+        window.mozRequestAnimationFrame    || 
+        window.oRequestAnimationFrame      || 
+        window.msRequestAnimationFrame     || 
+        function(/* function */ callback, /* DOMElement */ element){
+            window.setTimeout(callback, 1000 / 60);
+        };
+})();
+
+var WidgetGridViewer = function(python_varname, widget_data) {
+    this.id = python_varname;
+    this.widget_data = widget_data;
+    examine = "canvas_" + python_varname;
+    var draw;
+    var GridViewerStart = function() {
+        this.curX = 0;
+        this.curY = 0;
+        this.dist = 0;
+        function updateBasedOnOffset(camera, offset){
+            camera.position.x = camera.target.x + offset.x;
+            camera.position.y = camera.target.y + offset.y;
+            camera.position.z = camera.target.z + offset.z;
+            draw();
+        }
+        function camGetOffset(camera){
+            return PhiloGL.Vec3.sub(camera.position, camera.target)
+        }
+        PhiloGL('canvas_' + python_varname, {
+            camera: {
+		position: {
+                    x: 0.5, y: 0.5, z: 5
+		},
+                target: {
+                    x: 0.5, y: 0.5, z: 0.5
+                },
+            },
+            events: {
+		onDragStart: function(e) {
+                    pos = {
+			x: e.x,
+			y: e.y
+                    };
+                    this.curX = e.x;
+                    this.curY = e.y;
+                    this.dist = camGetOffset(this.camera).norm();
+		},
+                onDragEnd: function(e) {
+                    pos = {
+			x: e.x,
+			y: e.y
+                    };
+  		},
+                onDragMove: function(e) {
+                    var c = this.camera;
+                    var off = camGetOffset(c);
+
+                    // Get Horizontal vector
+                    var horiz = PhiloGL.Vec3.cross(c.up, 
+						   camGetOffset(c))
+                    horiz.$scale(1./horiz.norm());
+
+                    if (e.event.button == 0){ // Rotation
+			// Do vertical rotation about horizontal vector
+			var vert_rot = new PhiloGL.Mat4();
+			vert_rot.id();
+			vert_rot.$rotateAxis((e.y-this.curY)/100., horiz);
+			PhiloGL.Mat4.$mulVec3(vert_rot, off);
+			PhiloGL.Mat4.$mulVec3(vert_rot, c.up);
+			c.up.$scale(1./c.up.norm());
+
+			// Do horizontal rotation about up vector
+			var side_rot = new PhiloGL.Mat4();
+			side_rot.id();
+			side_rot.$rotateAxis(-(e.x-this.curX)/100., c.up);
+			side_rot.$mulVec3(off);
+			
+			// Update current positions
+			this.curX = e.x;
+			this.curY = e.y;
+			this.dist = off.norm();
+			updateBasedOnOffset(c, off);
+			this.camera.near = this.dist/100000.0;
+			this.camera.far = this.dist*2.0;
+			c.update();
+                    } else if (e.event.button = 2){ // Right click - transpose
+			var tscale = 1.0*off.norm()/512.;
+			var move_up = c.up.scale(-(e.y-this.curY)*tscale);
+			var move_over = horiz.scale(-(e.x-this.curX)*tscale);
+			c.position.$add(move_up);
+			c.position.$add(move_over);
+			c.target.$add(move_up);
+			c.target.$add(move_over);
+			// Update current positions
+			this.curX = e.x;
+			this.curY = e.y;
+			this.dist = off.norm();
+			this.camera.near = this.dist/100000.0;
+			this.camera.far = this.dist*2.0;
+			c.update();
+                    }
+		    draw();
+		},
+                onMouseWheel: function(e){
+                    e.stop();
+                    var offset = PhiloGL.Vec3.scale(camGetOffset(this.camera),
+						    1.0 - e.wheel/10.);
+                    updateBasedOnOffset(this.camera, offset);
+		    var dist = offset.norm()
+                    this.camera.near = offset.norm()/100000.0;
+                    this.camera.far = offset.norm()*2.0;
+                    this.camera.update();
+                    draw();
+		}
+            },
+            onError: function() {
+		alert("An error ocurred while loading the application");
+            },
+            onLoad: function(app) {
+		var gl = app.gl,
+                canvas = app.canvas,
+                program = app.program,
+                scene = app.scene,
+                camera = app.camera;
+		var grids = new PhiloGL.O3D.Model({
+            vertices : widget_data['vertex_positions'],
+            drawType : "LINES",
+            colors : widget_data['vertex_colors'],
+        });
+        scene.add(grids);
+		gl.viewport(0, 0, canvas.width, canvas.height);
+		gl.clearColor(0, 0, 0, 1);
+
+		//examine = camera;
+		camera.view.id();
+		camera.update();
+		
+		//Draw the scene
+		draw = function() {
+	    	    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+                scene.render();
+		}
+
+		draw();
+
+	    }
+        });  
+    }        
+
+    viewport.get("center-panel").add(
+        {
+            xtype: 'panel',
+            id: "gv_" + python_varname,
+            title: "WebGL Grid Viewer",
+            iconCls: 'graph',
+            autoScroll: true,
+            layout:'absolute',
+            closable: true,
+            items: [
+                { xtype:'panel',
+                  autoEl: {
+                      tag: 'canvas',
+                      id: 'canvas_' + python_varname,
+                      style: 'border: none;',
+                      width: 512, height:512
+                  },
+                  width: 512,
+                  height: 512
+                }],
+            listeners: { afterlayout: GridViewerStart },
+        }
+    );
+
+    viewport.get("center-panel").activate("gv_" + this.id);
+    viewport.doLayout();
+    this.panel = viewport.get("center-panel").get("gv_" + python_varname);
+    this.panel.doLayout();
+
+    this.accept_results = function(payload) { }
+}
+
+widget_types['grid_viewer'] = WidgetGridViewer;


diff -r 47094c9542e2ad48b54789108882ddcf8faf9285 -r 62ef095a290cc6041ee9cb44794535b8884b2e0f yt/gui/reason/html/app/controller/widgets/IsocontourViewer.js
--- /dev/null
+++ b/yt/gui/reason/html/app/controller/widgets/IsocontourViewer.js
@@ -0,0 +1,213 @@
+/**********************************************************************
+The isocontour viewer widget
+
+Author: Samuel Skillman <samskillman at gmail.com>
+Affiliation: University of Colorado at Boulder
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+// shim layer with setTimeout fallback
+window.requestAnimFrame = (function(){
+    return  window.requestAnimationFrame       || 
+        window.webkitRequestAnimationFrame || 
+        window.mozRequestAnimationFrame    || 
+        window.oRequestAnimationFrame      || 
+        window.msRequestAnimationFrame     || 
+        function(/* function */ callback, /* DOMElement */ element){
+            window.setTimeout(callback, 1000 / 60);
+        };
+})();
+
+var exagain;
+var WidgetIsocontourViewer = function(python_varname, widget_data) {
+    this.id = python_varname;
+    this.widget_data = widget_data;
+    examine = "canvas_" + python_varname;
+    var draw;
+    var GridViewerStart = function() {
+        this.curX = 0;
+        this.curY = 0;
+        this.dist = 0;
+        function updateBasedOnOffset(camera, offset){
+            camera.position.x = camera.target.x + offset.x;
+            camera.position.y = camera.target.y + offset.y;
+            camera.position.z = camera.target.z + offset.z;
+            draw();
+        }
+        function camGetOffset(camera){
+            return PhiloGL.Vec3.sub(camera.position, camera.target)
+        }
+        PhiloGL('canvas_' + python_varname, {
+            camera: {
+		position: {
+                    x: 0.5, y: 0.5, z: 5
+		},
+                target: {
+                    x: 0.5, y: 0.5, z: 0.5
+                },
+            },
+            events: {
+		onDragStart: function(e) {
+                    pos = {
+			x: e.x,
+			y: e.y
+                    };
+                    this.curX = e.x;
+                    this.curY = e.y;
+                    this.dist = camGetOffset(this.camera).norm();
+		},
+                onDragEnd: function(e) {
+                    pos = {
+			x: e.x,
+			y: e.y
+                    };
+  		},
+                onDragMove: function(e) {
+                    var c = this.camera;
+                    var off = camGetOffset(c);
+
+                    // Get Horizontal vector
+                    var horiz = PhiloGL.Vec3.cross(c.up, 
+						   camGetOffset(c))
+                    horiz.$scale(1./horiz.norm());
+
+                    if (e.event.button == 0){ // Rotation
+			// Do vertical rotation about horizontal vector
+			var vert_rot = new PhiloGL.Mat4();
+			vert_rot.id();
+			vert_rot.$rotateAxis((e.y-this.curY)/100., horiz);
+			PhiloGL.Mat4.$mulVec3(vert_rot, off);
+			PhiloGL.Mat4.$mulVec3(vert_rot, c.up);
+			c.up.$scale(1./c.up.norm());
+
+			// Do horizontal rotation about up vector
+			var side_rot = new PhiloGL.Mat4();
+			side_rot.id();
+			side_rot.$rotateAxis(-(e.x-this.curX)/100., c.up);
+			side_rot.$mulVec3(off);
+			
+			// Update current positions
+			this.curX = e.x;
+			this.curY = e.y;
+			this.dist = off.norm();
+			updateBasedOnOffset(c, off);
+			this.camera.near = this.dist/100000.0;
+			this.camera.far = this.dist*2.0;
+			c.update();
+                    } else if (e.event.button = 2){ // Right click - transpose
+			var tscale = 1.0*off.norm()/512.;
+			var move_up = c.up.scale(-(e.y-this.curY)*tscale);
+			var move_over = horiz.scale(-(e.x-this.curX)*tscale);
+			c.position.$add(move_up);
+			c.position.$add(move_over);
+			c.target.$add(move_up);
+			c.target.$add(move_over);
+			// Update current positions
+			this.curX = e.x;
+			this.curY = e.y;
+			this.dist = off.norm();
+			this.camera.near = this.dist/100000.0;
+			this.camera.far = this.dist*2.0;
+			c.update();
+                    }
+		    draw();
+		},
+                onMouseWheel: function(e){
+                    e.stop();
+                    var offset = PhiloGL.Vec3.scale(camGetOffset(this.camera),
+						    1.0 - e.wheel/10.);
+                    updateBasedOnOffset(this.camera, offset);
+		    var dist = offset.norm()
+                    this.camera.near = offset.norm()/100000.0;
+                    this.camera.far = offset.norm()*2.0;
+                    this.camera.update();
+                    draw();
+		}
+            },
+            onError: function() {
+		alert("An error ocurred while loading the application");
+            },
+            onLoad: function(app) {
+		var gl = app.gl,
+                canvas = app.canvas,
+                program = app.program,
+                scene = app.scene,
+                camera = app.camera;
+		var grids = new PhiloGL.O3D.Model({
+            vertices : widget_data['vertex_positions'],
+            drawType : "TRIANGLES",
+            colors : widget_data['vertex_colors'],
+        });
+        exagain = grids;
+        scene.add(grids);
+		gl.viewport(0, 0, canvas.width, canvas.height);
+		gl.clearColor(0, 0, 0, 1);
+
+		//examine = camera;
+		camera.view.id();
+		camera.update();
+		
+		//Draw the scene
+		draw = function() {
+	    	    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+                scene.render();
+		}
+
+		draw();
+
+	    }
+        });  
+    }        
+
+    viewport.get("center-panel").add(
+        {
+            xtype: 'panel',
+            id: "iv_" + python_varname,
+            title: "WebGL Isocontour Viewer",
+            iconCls: 'graph',
+            autoScroll: true,
+            layout:'absolute',
+            closable: true,
+            items: [
+                { xtype:'panel',
+                  autoEl: {
+                      tag: 'canvas',
+                      id: 'canvas_' + python_varname,
+                      style: 'border: none;',
+                      width: 512, height:512
+                  },
+                  width: 512,
+                  height: 512
+                }],
+            listeners: { afterlayout: GridViewerStart },
+        }
+    );
+
+    viewport.get("center-panel").activate("iv_" + this.id);
+    viewport.doLayout();
+    this.panel = viewport.get("center-panel").get("iv_" + python_varname);
+    this.panel.doLayout();
+
+    this.accept_results = function(payload) { }
+}
+
+widget_types['isocontour_viewer'] = WidgetIsocontourViewer;


diff -r 47094c9542e2ad48b54789108882ddcf8faf9285 -r 62ef095a290cc6041ee9cb44794535b8884b2e0f yt/gui/reason/html/app/controller/widgets/PannableMap.js
--- /dev/null
+++ b/yt/gui/reason/html/app/controller/widgets/PannableMap.js
@@ -0,0 +1,76 @@
+/**********************************************************************
+The Pannable Map Widget
+
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+var WidgetPannableMap = function(python_varname, widget_data) {
+    this.id = python_varname;
+    this.widget_data = widget_data;
+
+    viewport.get("center-panel").add(
+        {
+            xtype: 'panel',
+            id: "pm_" + this.id,
+            title: "Pannable Map",
+            iconCls: 'graph',
+            autoScroll: true,
+            layout:'absolute',
+            closable: true,
+            items: [ 
+                {
+                    xtype:'box',
+                    autoEl: {
+                        tag: 'div',
+                        id: "map_" + this.id,
+                        width: 512,
+                        height: 512,
+                    },
+                    x: 10,
+                    y: 10,
+                    width: 512,
+                    height: 512,
+                    listeners: {afterrender:
+                        function() {
+                          var map = new L.Map('map_' + python_varname, {
+                                  center: new L.LatLng(0.0, 0.0),
+                                  zoom: 0,
+                                  });
+                          var cloudmadeUrl = widget_data['prefix'] + '/map/{z}/{x}/{y}.png';
+                          cloudmade = new L.TileLayer(cloudmadeUrl, {maxZoom: 18});
+                          map.addLayer(cloudmade);
+                    }},
+                }  
+            ]
+        }
+    );
+
+    viewport.get("center-panel").activate("pm_" + this.id);
+    viewport.doLayout();
+    this.panel = viewport.get("center-panel").get("pm_" + this.id);
+    this.panel.doLayout();
+    examine = this.panel;
+
+    this.accept_results = function(payload) { }
+}
+
+widget_types['pannable_map'] = WidgetPannableMap;


diff -r 47094c9542e2ad48b54789108882ddcf8faf9285 -r 62ef095a290cc6041ee9cb44794535b8884b2e0f yt/gui/reason/html/app/controller/widgets/PhasePlot.js
--- /dev/null
+++ b/yt/gui/reason/html/app/controller/widgets/PhasePlot.js
@@ -0,0 +1,239 @@
+/**********************************************************************
+The Plot Window Widget
+
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+
+
+var WidgetPhasePlot = function(python_varname, widget_data) {
+    this.id = python_varname;
+    this.widget_data = widget_data;
+
+    viewport.get("center-panel").add(
+        {
+            xtype: 'panel',
+            id: "pp_" + this.id,
+            title: widget_data['title'],
+            iconCls: 'graph',
+            autoScroll: true,
+            layout:'absolute',
+            closable: true,
+            items: [ 
+                {
+                    xtype: 'panel',
+                    id: 'y_ticks_' + python_varname,
+                    layout: 'absolute',
+                    y: 10,
+                    x: 100,
+                    width: 40,
+                    height: 400,
+                    items : [],
+                    border: false,
+                }, {
+                    xtype: 'panel',
+                    id: 'x_ticks_' + python_varname,
+                    layout: 'absolute',
+                    y: 410,
+                    x: 140,
+                    width: 400,
+                    height: 40,
+                    items : [],
+                    border: false,
+                }, {
+                    xtype:'panel',
+                    id: 'image_panel_' + this.id,
+                    autoEl: {
+                        tag: 'img',
+                        id: "img_" + this.id,
+                        width: 400,
+                        height: 400,
+                        style: 'border: 1px solid #000000',
+                    },
+                    x: 138,
+                    y: 8,
+                    width: 400,
+                    height: 400,
+                }, {
+                    xtype:'panel',
+                    id: 'colorbar_' + python_varname,
+                    autoEl: {
+                        tag: 'img',
+                        id: "cb_" + python_varname,
+                        src: "data:image/png;base64," +
+                             widget_data['colorbar'],
+                        width: 28,
+                        height: 398,
+                        style: 'border: 1px solid #000000;',
+                    },
+                    x: 560,
+                    y: 10,
+                    width: 30,
+                    height: 400,
+                }, {
+                    xtype: 'panel',
+                    id: 'ticks_' + python_varname,
+                    layout: 'absolute',
+                    y: 10,
+                    x: 590,
+                    width: 40,
+                    height: 400,
+                    items : [],
+                    border: false,
+                },{
+                    xtype: 'button',
+                    text: 'Upload Image',
+                    x: 10,
+                    y: 285,
+                    width: 80,
+                    tooltip: "Upload the current image to " +
+                             "<a href='http://imgur.com'>imgur.com</a>",
+                    handler: function(b,e) {
+                        img_data = image_dom.src;
+                        yt_rpc.ExtDirectREPL.upload_image(
+                            {image_data:img_data,
+                             caption:metadata_string},
+                        function(rv) {
+                            var alert_text;
+                            if(rv['uploaded'] == false) {
+                                alert_text = "Failure uploading image!";
+                            } else {
+                                alert_text = "Uploaded to " +
+                                        rv['upload']['links']['imgur_page'];
+                            }
+                            Ext.Msg.alert('imgur.com', alert_text);
+                            var record = new logging_store.recordType(
+                                {record: alert_text });
+                            logging_store.add(record, number_log_records++);
+                        }); 
+                    }
+                },{
+                    xtype: 'panel',
+                    layout: 'vbox',
+                    id: 'rhs_panel_' + python_varname,
+                    width: 300,
+                    height: 460,
+                    x: 640, y: 10,
+                    layoutConfig: {
+                        align: 'stretch',
+                        pack: 'start',
+                    },
+                    items: [
+                        {
+                          xtype: 'panel',
+                          title: 'Plot MetaData',
+                          id: 'metadata_' + python_varname,
+                          style: {fontFamily: '"Inconsolata", monospace'},
+                          html: 'Welcome to the Plot Window.',
+                          height: 200,
+                        }, {
+                          xtype: 'panel',
+                          title: 'Plot Editor',
+                          id: 'plot_edit',
+                          flex: 1,
+                        }]
+                }
+            ]
+        }
+    );
+
+    viewport.get("center-panel").activate("pp_" + this.id);
+    viewport.get("center-panel").doLayout();
+    viewport.doLayout();
+    this.panel = viewport.get("center-panel").get("pp_" + python_varname);
+    this.panel.doLayout();
+    this.panel.show();
+    this.image_panel = this.panel.get("image_panel_"+python_varname);
+    this.ticks = this.panel.get("ticks_"+python_varname);
+    var x_ticks = this.panel.get("x_ticks_"+python_varname);
+    var y_ticks = this.panel.get("y_ticks_"+python_varname);
+    var ticks = this.ticks;
+    this.metadata_panel = this.panel.get("rhs_panel_" + python_varname).get("metadata_" + python_varname);
+    var image_dom = this.image_panel.el.dom;
+    var control_panel = this.panel;
+    var metadata_string;
+    var colorbar = this.panel.get("colorbar_"+python_varname);
+
+    this.accept_results = function(payload) {
+        this.image_panel.el.dom.src = "data:image/png;base64," + payload['image_data'];
+        examine = this.metadata_panel;
+        this.metadata_panel.update(payload['metadata_string']);
+        metadata_string = payload['metadata_string'];
+        ticks.removeAll();
+        colorbar.el.dom.src = "data:image/png;base64," +
+                              payload['cbar']['cmap_image'];
+        Ext.each(payload['yax']['ticks'], function(tick, index) {
+            examine = tick;
+            y_ticks.add({xtype:'panel',
+                       width: 20, height:15,
+                       border: false,
+                       style: 'font-family: "Inconsolata", monospace;' +
+                              'font-size: 12px; text-align: right;' +
+                              'padding-right: 5px;',
+                       html: ' ' + tick[2] + ' ',
+                       x:0, y: tick[0]-6});
+            y_ticks.add({xtype:'panel',
+                       width: 20, height:1,
+                       style: 'background-color: #000000;',
+                       html:' ',
+                       x:20, y: tick[0]});
+        });
+        y_ticks.doLayout();
+        Ext.each(payload['xax']['ticks'], function(tick, index) {
+            examine = tick;
+            x_ticks.add({xtype:'panel',
+                       width: 1, height:20,
+                       style: 'background-color: #000000;',
+                       html:' ',
+                       x:(400 - tick[0]) + 10, y: 0});
+            x_ticks.add({xtype:'panel',
+                       width: 20, height:20,
+                       border: false,
+                       style: 'font-family: "Inconsolata", monospace;' +
+                              'font-size: 12px; text-align: center;',
+                       html: ' ' + tick[2] + ' ',
+                       x: (400 - tick[0]), y: 20});
+        });
+        x_ticks.doLayout();
+        Ext.each(payload['cbar']['ticks'], function(tick, index) {
+            ticks.add({xtype:'panel',
+                       width: 10, height:1,
+                       style: 'background-color: #000000;',
+                       html:' ',
+                       x:0, y: tick[0]});
+            ticks.add({xtype:'panel',
+                       width: 30, height:15,
+                       border: false,
+                       style: 'font-family: "Inconsolata", monospace;' +
+                              'font-size: 12px;',
+                       html: ' ' + tick[2] + ' ',
+                       x:18, y: tick[0]-6});
+        });
+        ticks.doLayout();
+        x_ticks.doLayout();
+    }
+    yt_rpc.ExtDirectREPL.execute(
+        {code:python_varname + '._setup_plot()', hide:true},
+        cell_finished);
+}
+
+widget_types['phase_plot'] = WidgetPhasePlot;


diff -r 47094c9542e2ad48b54789108882ddcf8faf9285 -r 62ef095a290cc6041ee9cb44794535b8884b2e0f yt/gui/reason/html/app/controller/widgets/PlotWindow.js
--- /dev/null
+++ b/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
@@ -0,0 +1,732 @@
+/**********************************************************************
+The Plot Window Widget
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+
+
+var WidgetPlotWindow = function(python_varname, widget_data) {
+    this.id = python_varname;
+    this.widget_data = widget_data;
+    this.print_python = function(b, e) {
+        yt_rpc.ExtDirectREPL.execute(
+            {code:'print "' + python_varname + '"',
+             hide:true},
+            function(f, a) {alert(a.result['output']);}
+        );
+    }
+
+    this.widget_keys = new Ext.KeyMap(document, [
+        {key: 'z',
+         shift: false,
+         fn: function(){
+               control_panel.get("zoom2x").handler();
+            }
+        },
+        {key: 'Z',
+         shift: true,
+         fn: function(){
+               control_panel.get("zoom10x").handler();
+            }
+        },
+        {key: 'x',
+         shift: false,
+         fn: function(){
+               control_panel.get("zoomout2x").handler();
+            }
+        },
+        {key: 'X',
+         shift: true,
+         fn: function(){
+               control_panel.get("zoomout10x").handler();
+            }
+        },
+        {key: 'k',
+         shift: false,
+         fn: function(){
+               control_panel.get("singleuparrow").handler();
+            }
+        },
+        {key: 'j',
+         shift: false,
+         fn: function(){
+               control_panel.get("singledownarrow").handler();
+            }
+        },
+        {key: 'h',
+         shift: false,
+         fn: function(){
+               control_panel.get("singleleftarrow").handler();
+            }
+        },
+        {key: 'l',
+         shift: false,
+         fn: function(){
+               control_panel.get("singlerightarrow").handler();
+            }
+        },
+        {key: 'K',
+         shift: true,
+         fn: function(){
+               control_panel.get("doubleuparrow").handler();
+            }
+        },
+        {key: 'J',
+         shift: true,
+         fn: function(){
+               control_panel.get("doubledownarrow").handler();
+            }
+        },
+        {key: 'H',
+         shift: true,
+         fn: function(){
+               control_panel.get("doubleleftarrow").handler();
+            }
+        },
+        {key: 'L',
+         shift: true,
+         fn: function(){
+               control_panel.get("doublerightarrow").handler();
+            }
+        },
+    ]);
+    var widget_keys = this.widget_keys;
+    widget_keys.disable();
+    widget_keys.varname = python_varname;
+
+    viewport.get("center-panel").add(
+        {
+            xtype: 'panel',
+            id: "pw_" + this.id,
+            title: widget_data['title'],
+            iconCls: 'graph',
+            autoScroll: true,
+            layout:'absolute',
+            closable: true,
+            listeners: {activate: function(p){
+                                widget_keys.enable();
+                            },
+                        deactivate: function(p){
+                                widget_keys.disable();
+                            }
+                        },
+            items: [ 
+                {
+                    xtype:'panel',
+                    id: 'image_panel_' + this.id,
+                    autoEl: {
+                        tag: 'img',
+                        id: "img_" + this.id,
+                        width: 400,
+                        height: 400,
+                        draggable: false,
+                    },
+                    x: 100,
+                    y: 10,
+                    width: 400,
+                    height: 400,
+                    draggable: false,
+                    listeners: {
+                        afterrender: function(c){
+                            c.el.on('click', function(e){
+                                if (e.ctrlKey == false) return;
+                                xy = e.getXY();
+                                cc = python_varname + ".image_recenter(" 
+                                    + (xy[0] - c.el.dom.x) + ", "
+                                    + (xy[1] - c.el.dom.y) + ", "
+                                    + c.el.dom.width + ", "
+                                    + c.el.dom.height + ")";
+                                yt_rpc.ExtDirectREPL.execute(
+                                {code:cc, hide:true}, cell_finished); 
+                            });
+                            c.el.on('mousedown', function(e){
+                                c.drag_start = true;
+                                c.drag_start_pos = e.getXY();
+                            });
+                            c.el.on('mouseup', function(e){
+                                c.drag_start = false;
+                                drag_stop = e.getXY();
+                                delta_x = drag_stop[0] - c.drag_start_pos[0];
+                                delta_y = drag_stop[1] - c.drag_start_pos[1];
+                                if (((delta_x < -10) || (delta_x > 10)) ||
+                                    ((delta_y < -10) || (delta_y > 10))) {
+                                    rel_x = -delta_x / 400;
+                                    rel_y = -delta_y / 400;
+                                    cc = python_varname + '.pan_rel((' + 
+                                        rel_x + ',' + rel_y + '))';
+                                    yt_rpc.ExtDirectREPL.execute(
+                                    {code:cc, hide:true}, cell_finished); 
+                                }
+                            });
+                        }
+                    }
+                }, {
+                    xtype:'panel',
+                    id: 'colorbar_' + python_varname,
+                    autoEl: {
+                        tag: 'img',
+                        id: "cb_" + python_varname,
+                        src: "data:image/png;base64," +
+                             widget_data['colorbar'],
+                        width: 28,
+                        height: 398,
+                        style: 'border: 1px solid #000000;',
+                    },
+                    x: 510,
+                    y: 10,
+                    width: 30,
+                    height: 400,
+                }, {
+                    xtype: 'panel',
+                    id: 'ticks_' + python_varname,
+                    layout: 'absolute',
+                    y: 0,
+                    x: 540,
+                    width: 100,
+                    height: 420,
+                    items : [],
+                    border: false,
+                }, {   xtype: 'multislider',
+                    id: 'slider_' + python_varname,
+                    minValue: 0,
+                    maxValue: 100,
+                    increment: 0.1,
+                    x: 100, y: 410,
+                    width: 400,
+                    listeners: {
+                        /* Only changecomplete; don't want too many render
+                        events */
+                        changecomplete: function(slider, newValue, thumb) {
+                            yt_rpc.ExtDirectREPL.execute(
+                                {code:python_varname + ".scroll_zoom(" +
+                                      newValue + ")",
+                                 hide:true}, cell_finished);
+                        }
+                    }
+                },{
+                    xtype: 'combo',
+                    text: 'Field',
+                    x: 100,
+                    y: 435,
+                    width: 400,
+                    store:widget_data['fields'],
+                    value:widget_data['initial_field'],
+                    editable: false,
+                    triggerAction: 'all',
+                    validateOnBlur: false,
+                    listeners: {select: function(combo, record, index) {
+                        var newValue = record.data['field1'];
+                        yt_rpc.ExtDirectREPL.execute(
+                            {code:python_varname + '.set_current_field("' +
+                                newValue + '")', hide:false},
+                            cell_finished);
+                    }}
+                }, {
+                /* the single buttons for 10% pan*/
+                    xtype:'button',
+                    iconCls: 'singleuparrow',
+                    id: 'singleuparrow',
+                    //text: 'North',
+                    x: 40,
+                    y: 10,
+                    handler: function(b,e) {
+                        cc = python_varname + '.pan_rel((0.0, -0.1))'
+                        yt_rpc.ExtDirectREPL.execute(
+                        {code:cc, hide:true}, cell_finished); 
+                    }
+                }, {
+                    xtype:'button',
+                    iconCls: 'singlerightarrow',
+                    id: 'singlerightarrow',
+                    //text:'East',
+                    x : 60,
+                    y : 30,
+                    handler: function(b,e) {
+                        yt_rpc.ExtDirectREPL.execute(
+                            {code:python_varname + '.pan_rel((0.1, 0.0))',
+                             hide:true},
+                        cell_finished); 
+                    }
+                }, {
+                    xtype:'button',
+                    iconCls: 'singledownarrow',
+                    id: 'singledownarrow',
+                    //text: 'South',
+                    x: 40,
+                    y: 50,
+                    handler: function(b,e) {
+                        yt_rpc.ExtDirectREPL.execute(
+                            {code:python_varname + '.pan_rel((0.0, 0.1))',
+                             hide:true},
+                        cell_finished); 
+                    }
+                }, {
+                    xtype: 'button',
+                    iconCls: 'singleleftarrow',
+                    id: 'singleleftarrow',
+                    //text: 'West',
+                    x: 20,
+                    y: 30,
+                    handler: function(b,e) {
+                        yt_rpc.ExtDirectREPL.execute(
+                            {code:python_varname + '.pan_rel((-0.1, 0.0))',
+                             hide:true},
+                        cell_finished); 
+                    }
+                }, 
+                /* the double buttons for 50% pan*/
+                {
+                    xtype:'button',
+                    iconCls: 'doubleuparrow',
+                    id:'doubleuparrow',
+                    //text: 'North',
+                    x: 40,
+                    y: 80,
+                    handler: function(b,e) {
+                        cc = python_varname + '.pan_rel((0.0, -0.5))'
+                        yt_rpc.ExtDirectREPL.execute(
+                        {code:cc, hide:true}, cell_finished); 
+                    }
+                }, {
+                    xtype:'button',
+                    iconCls: 'doublerightarrow',
+                    id:'doublerightarrow',
+                    //text:'East',
+                    x : 60,
+                    y : 100,
+                    handler: function(b,e) {
+                        yt_rpc.ExtDirectREPL.execute(
+                            {code:python_varname + '.pan_rel((0.5, 0.0))',
+                             hide:true},
+                        cell_finished); 
+                    }
+                }, {
+                    xtype:'button',
+                    iconCls: 'doubledownarrow',
+                    //text: 'South',
+                    id: 'doubledownarrow',
+                    x: 40,
+                    y: 120,
+                    handler: function(b,e) {
+                        yt_rpc.ExtDirectREPL.execute(
+                            {code:python_varname + '.pan_rel((0.0, 0.5))',
+                             hide:true},
+                        cell_finished); 
+                    }
+                }, {
+                    xtype: 'button',
+                    iconCls: 'doubleleftarrow',
+                    id: 'doubleleftarrow',
+                    //text: 'West',
+                    x: 20,
+                    y: 100,
+                    handler: function(b,e) {
+                        yt_rpc.ExtDirectREPL.execute(
+                            {code:python_varname + '.pan_rel((-0.5, 0.0))',
+                             hide:true},
+                        cell_finished); 
+                    }
+                },
+                /* Now the zoom buttons */
+                {
+                    xtype: 'button',
+                    text: 'Zoom In 10x',
+                    id: "zoom10x",
+                    x: 10,
+                    y: 160,
+                    width: 80,
+                    handler: function(b,e) {
+                        yt_rpc.ExtDirectREPL.execute(
+                            {code:python_varname + '.zoom(10.0)',
+                             hide:true},
+                        cell_finished); 
+                    }
+                },{
+                    xtype: 'button',
+                    text: 'Zoom In 2x',
+                    id: "zoom2x",
+                    x: 10,
+                    y: 185,
+                    width: 80,
+                    handler: function(b,e) {
+                        yt_rpc.ExtDirectREPL.execute(
+                            {code:python_varname + '.zoom(2.0)',
+                             hide:true},
+                        cell_finished); 
+                    }
+                },{
+                    xtype: 'button',
+                    text: 'Zoom Out 2x',
+                    id:'zoomout2x',
+                    x: 10,
+                    y: 210,
+                    width: 80,
+                    handler: function(b,e) {
+                        yt_rpc.ExtDirectREPL.execute(
+                            {code:python_varname + '.zoom(0.5)',
+                             hide:true},
+                        cell_finished); 
+                    }
+                },{
+                    xtype: 'button',
+                    text: 'Zoom Out 10x',
+                    id:'zoomout10x',
+                    x: 10,
+                    y: 235,
+                    width: 80,
+                    handler: function(b,e) {
+                        yt_rpc.ExtDirectREPL.execute(
+                            {code:python_varname + '.zoom(0.1)',
+                             hide:true},
+                        cell_finished); 
+                    }
+                },{
+                    xtype: 'button',
+                    text: 'Upload Image',
+                    x: 10,
+                    y: 285,
+                    width: 80,
+                    tooltip: "Upload the current image to " +
+                             "<a href='http://imgur.com'>imgur.com</a>",
+                    handler: function(b,e) {
+                        img_data = image_dom.src;
+                        yt_rpc.ExtDirectREPL.upload_image(
+                            {image_data:img_data,
+                             caption:metadata_string},
+                        function(rv) {
+                            var alert_text;
+                            if(rv['uploaded'] == false) {
+                                alert_text = "Failure uploading image!";
+                            } else {
+                                alert_text = "Uploaded to " +
+                                        rv['upload']['links']['imgur_page'];
+                            }
+                            Ext.Msg.alert('imgur.com', alert_text);
+                            var record = new logging_store.recordType(
+                                {record: alert_text });
+                            logging_store.add(record, number_log_records++);
+                        }); 
+                    }
+                },{
+                    xtype: 'button',
+                    text: 'Pannable Map',
+                    x: 10,
+                    y: 335,
+                    width: 80,
+                    tooltip: "Open a pannable map in a new tab",
+                    handler: function(b,e) {
+                        img_data = image_dom.src;
+                        yt_rpc.ExtDirectREPL.create_mapview(
+                            {widget_name:python_varname},
+                        function(rv) {
+                            /*alert(rv);*/
+                        }); 
+                    }
+                },{
+                    xtype: 'panel',
+                    layout: 'vbox',
+                    id: 'rhs_panel_' + python_varname,
+                    width: 250,
+                    height: 460,
+                    x: 690, y: 10,
+                    layoutConfig: {
+                        align: 'stretch',
+                        pack: 'start',
+                    },
+                    items: [
+                        {
+                          xtype: 'panel',
+                          title: 'Plot MetaData',
+                          id: 'metadata_' + python_varname,
+                          style: {fontFamily: '"Inconsolata", monospace'},
+                          html: 'Welcome to the Plot Window.',
+                          height: 200,
+                        }, {
+                          xtype: 'tabpanel',
+                          id: 'editor_panel',
+                          flex: 1,
+                          activeTab: 0,
+                          items: [
+                        {
+                          xtype: 'panel',
+                          title: 'Plot Editor',
+                          id: 'plot_edit',
+                          style: {fontFamily: '"Inconsolata", monospace'},
+                          layout: 'absolute',
+                          flex: 1,
+                          items : [
+                             {
+                               x: 10,
+                               y: 20,
+                               width: 70,
+                               xtype: 'label',
+                               text: 'Display',
+                             },
+                             {
+                               x: 80,
+                               y: 20,
+                               width : 80,
+                               xtype: 'combo',
+                               editable: false,
+                               triggerAction: 'all',
+                               validateOnBlur: false,
+                               store: ['log10', 'linear'],
+                               value: widget_data['initial_transform'],
+                               listeners: {select: function(combo, record, index){ 
+                                   var newValue = '"' + record.data['field1'] + '"';
+                                   yt_rpc.ExtDirectREPL.execute(
+                                       {code:python_varname + '.set_transform('
+                                         + python_varname + '._current_field, '
+                                         + newValue + ')', hide:false},
+                                         cell_finished);
+                               }}
+                             },
+                             {
+                               x: 10,
+                               y: 60,
+                               width: 70,
+                               xtype: 'label',
+                               text: 'Colormap',
+                             },
+                             {
+                               x: 80,
+                               y: 60,
+                               width : 140,
+                               xtype: 'combo',
+                               editable: false,
+                               triggerAction: 'all',
+                               validateOnBlur: false,
+                               store: ['algae', 'RdBu', 'gist_stern',  
+                                       'hot', 'jet', 'kamae', 
+                                        'B-W LINEAR', 'BLUE',
+                                        'GRN-RED-BLU-WHT', 'RED TEMPERATURE',
+                                        'BLUE', 'STD GAMMA-II', 'PRISM',
+                                        'RED-PURPLE', 'GREEN', 'GRN',
+                                        'GREEN-PINK', 'BLUE-RED', '16 LEVEL',
+                                        'RAINBOW', 'STEPS', 'STERN SPECIAL',
+                                        'Haze', 'Blue - Pastel - Red',
+                                        'Pastels', 'Hue Sat Lightness 1',
+                                        'Hue Sat Lightness 2', 'Hue Sat Value 1',
+                                        'Hue Sat Value 2', 'Purple-Red + Stripes',
+                                        'Beach', 'Mac Style', 'Eos A', 'Eos B',
+                                        'Hardcandy', 'Nature', 'Ocean', 'Peppermint',
+                                        'Plasma', 'Blue-Red', 'Rainbow', 'Blue Waves',
+                                        'Volcano', 'Waves', 'Rainbow18',
+                                        'Rainbow + white', 'Rainbow + black'],
+                               value: 'algae',
+                               listeners: {select: function(combo, record, index){ 
+                                   var newValue = '"' + record.data['field1'] + '"';
+                                   yt_rpc.ExtDirectREPL.execute(
+                                       {code:python_varname + '.set_cmap('
+                                         + python_varname + '._current_field, '
+                                         + newValue + ')', hide:false},
+                                         cell_finished);
+                               }}
+                             }
+                          ]
+                        }, {
+                          xtype: 'panel',
+                          title: 'Contours',
+                          id: 'contour_edit',
+                          style: {fontFamily: '"Inconsolata", monospace'},
+                          layout: 'absolute',
+                          flex: 1,
+                          items : [
+                             {
+                               x: 10,
+                               y: 20,
+                               width: 70,
+                               xtype: 'label',
+                               text: 'Field',
+                             }, {
+                               x: 80,
+                               y: 20,
+                               width : 160,
+                               xtype: 'combo',
+                               editable: false,
+                               id: 'field',
+                               triggerAction: 'all',
+                               validateOnBlur: false,
+                               value:widget_data['initial_field'],
+                               store: widget_data['fields'],
+                             }, {
+                               x: 10,
+                               y: 60,
+                               width: 70,
+                               xtype: 'label',
+                               text: 'Levels',
+                             }, {
+                               x: 80,
+                               y: 60,
+                               width : 160,
+                               xtype: 'slider',
+                               id: 'ncont',
+                               minValue: 0,
+                               maxValue: 10,
+                               value: 5,
+                               increment: 1,
+                               plugins: new Ext.slider.Tip(),
+                             }, {
+                               x: 10,
+                               y: 100,
+                               width: 70,
+                               xtype: 'label',
+                               text: 'Logspaced',
+                             }, {
+                               x: 80,
+                               y: 100,
+                               width : 160,
+                               xtype: 'checkbox',
+                               id: 'logit',
+                               checked: true,
+                             }, {
+                               x: 10,
+                               y: 180,
+                               width: 80,
+                               xtype: 'button',
+                               text: 'Apply',
+                               handler: function(b, e) {
+                                  field = contour_window.get('field').getValue();
+                                  ncont = contour_window.get('ncont').getValue();
+                                  logit = contour_window.get('logit').getValue();
+                                  if (logit == false) logit = 'False';
+                                  else if (logit == true) logit = 'True';
+                                  yt_rpc.ExtDirectREPL.execute(
+                                      {code:python_varname
+                                       + '.set_contour_info("' + field + '", '
+                                       + ncont + ', ' + logit + ')',
+                                        hide:false},
+                                      cell_finished);
+                               }
+                             }
+                          ]
+                        }, {
+                          xtype: 'panel',
+                          title: 'Velocity Vectors',
+                          id: 'vector_edit',
+                          style: {fontFamily: '"Inconsolata", monospace'},
+                          layout: 'absolute',
+                          flex: 1,
+                          items : [
+                             {
+                               x: 10,
+                               y: 60,
+                               width: 70,
+                               xtype: 'label',
+                               text: 'Skip Factor',
+                             }, {
+                               x: 80,
+                               y: 60,
+                               width : 160,
+                               xtype: 'slider',
+                               id: 'skip',
+                               minValue: 1,
+                               maxValue: 64,
+                               value: 32,
+                               increment: 1,
+                               plugins: new Ext.slider.Tip(),
+                             }, {
+                               x: 10,
+                               y: 180,
+                               width: 80,
+                               xtype: 'button',
+                               text: 'Apply',
+                               handler: function(b, e) {
+                                  skip = vector_window.get('skip').getValue();
+                                  yt_rpc.ExtDirectREPL.execute(
+                                      {code:python_varname
+                                       + '.set_vector_info('+skip+')',
+                                        hide:false},
+                                      cell_finished);
+                               }
+                             }
+                          ]
+                        }
+                        ] } /* tabpanel items and entry */
+                        ]
+                }
+            ]
+        }
+    );
+
+    viewport.get("center-panel").activate("pw_" + this.id);
+    viewport.get("center-panel").doLayout();
+    viewport.doLayout();
+    this.panel = viewport.get("center-panel").get("pw_" + python_varname);
+    this.panel.doLayout();
+    this.panel.show();
+    this.image_panel = this.panel.get("image_panel_"+python_varname);
+    this.ticks = this.panel.get("ticks_"+python_varname);
+    var ticks = this.ticks;
+    var colorbar = this.panel.get("colorbar_"+python_varname);
+    this.metadata_panel = this.panel.get("rhs_panel_" + python_varname).get("metadata_" + python_varname);
+    this.zoom_scroll = this.panel.get("slider_" + python_varname);
+    var contour_window = this.panel.get("rhs_panel_" + python_varname);
+    contour_window = contour_window.get("editor_panel");
+    contour_window = contour_window.get("contour_edit");
+    var vector_window = this.panel.get("rhs_panel_" + python_varname);
+    vector_window = vector_window.get("editor_panel");
+    vector_window = vector_window.get("vector_edit");
+    var image_dom = this.image_panel.el.dom;
+    var control_panel = this.panel;
+    var metadata_string;
+
+    this.accept_results = function(payload) {
+        this.image_panel.el.dom.src = "data:image/png;base64," + payload['image_data'];
+        this.zoom_scroll.setValue(0, payload['zoom'], true);
+        this.metadata_panel.update(payload['metadata_string']);
+        metadata_string = payload['metadata_string'];
+        ticks.removeAll();
+        Ext.each(payload['ticks'], function(tick, index) {
+            ticks.add({xtype:'panel',
+                       width: 10, height:1,
+                       style: 'background-color: #000000;',
+                       html:' ',
+                       x:0, y: 10 + tick[0]});
+            ticks.add({xtype:'panel',
+                       width: 90, height:15,
+                       border: false,
+                       style: 'font-family: "Inconsolata", monospace;' +
+                              'font-size: 12px;',
+                       html: '' + tick[2] + '',
+                       x:12, y: 4 + tick[0]});
+        });
+        if (payload['colorbar_image'] != null) {
+            colorbar.el.dom.src = "data:image/png;base64," +
+                payload['colorbar_image'];
+        }
+        ticks.doLayout();
+    }
+
+    yt_rpc.ExtDirectREPL.execute(
+        {code:python_varname + '.zoom(1.0)', hide:true},
+        cell_finished);
+}
+
+widget_types['plot_window'] = WidgetPlotWindow;


diff -r 47094c9542e2ad48b54789108882ddcf8faf9285 -r 62ef095a290cc6041ee9cb44794535b8884b2e0f yt/gui/reason/html/app/controller/widgets/ProgressBar.js
--- /dev/null
+++ b/yt/gui/reason/html/app/controller/widgets/ProgressBar.js
@@ -0,0 +1,51 @@
+/**********************************************************************
+The Plot Window Widget
+
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+
+
+var WidgetProgressBar = function(python_varname, widget_data) {
+    this.id = 'pbar_top';
+
+    Ext.MessageBox.show({
+        title: 'yt is working ...',
+        msg: widget_data.title,
+        progressText: 'Progress',
+        width: 300,
+        progress: true,
+        closable: false,
+    });
+
+    this.accept_results = function(payload) {
+        var i = payload['value'];
+        if (i == -1) {
+            Ext.MessageBox.hide();
+        } else {
+            Ext.MessageBox.updateProgress(i, Math.round(100*i)+'% completed');
+        }
+    }
+
+}
+
+widget_types['progressbar'] = WidgetProgressBar;


diff -r 47094c9542e2ad48b54789108882ddcf8faf9285 -r 62ef095a290cc6041ee9cb44794535b8884b2e0f yt/gui/reason/html/app/controller/widgets/StreamlineViewer.js
--- /dev/null
+++ b/yt/gui/reason/html/app/controller/widgets/StreamlineViewer.js
@@ -0,0 +1,217 @@
+/**********************************************************************
+The Streamline Viewer Widget
+
+Author: Samuel Skillman <samskillman at gmail.com>
+Affiliation: University of Colorado at Boulder
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+
+
+var WidgetStreamlineViewer = function(python_varname, widget_data) {
+    this.id = python_varname;
+    this.widget_data = widget_data;
+    examine = "canvas_" + python_varname;
+    var StreamlineViewerStart = function() {
+        this.curX = 0;
+        this.curY = 0;
+        this.dist = 0;
+        function updateBasedOnOffset(camera, offset){
+        camera.position.x = camera.target.x + offset.x;
+        camera.position.y = camera.target.y + offset.y;
+        camera.position.z = camera.target.z + offset.z;
+        }
+        function camGetOffset(camera){
+        return PhiloGL.Vec3.sub(camera.position, camera.target)
+            }
+        PhiloGL('canvas_' + python_varname, {
+            camera: {
+            position: {
+                x: 0.5, y: 0.5, z: 5
+                },
+                target: {
+                x: 0.5, y: 0.5, z: 0.5
+                },
+                },
+            program: {
+            from: 'ids',
+                vs: 'sl-shader-vs',
+                fs: 'sl-shader-fs'
+                },    
+            events: {
+            onDragStart: function(e) {
+                pos = {
+                x: e.x,
+                y: e.y
+                };
+                this.curX = e.x;
+                this.curY = e.y;
+                this.dist = camGetOffset(this.camera).norm();
+            },
+                onDragEnd: function(e) {
+                pos = {
+                x: e.x,
+                y: e.y
+                };
+            },
+                onDragMove: function(e) {
+                var c = this.camera;
+                var off = camGetOffset(c);
+                // Get Horizontal vector
+                var horiz = PhiloGL.Vec3.cross(c.up, 
+                               camGetOffset(c))
+                horiz.$scale(1./horiz.norm());
+
+                if (e.event.button == 0){ // Rotation
+                // Do vertical rotation about horizontal vector
+                var vert_rot = new PhiloGL.Mat4();
+                vert_rot.id();
+                vert_rot.$rotateAxis((e.y-this.curY)/100., horiz);
+                PhiloGL.Mat4.$mulVec3(vert_rot, off);
+                PhiloGL.Mat4.$mulVec3(vert_rot, c.up);
+                c.up.$scale(1./c.up.norm());
+
+                // Do horizontal rotation about up vector
+                var side_rot = new PhiloGL.Mat4();
+                side_rot.id();
+                side_rot.$rotateAxis(-(e.x-this.curX)/100., c.up);
+                side_rot.$mulVec3(off);
+        
+                // Update current positions
+                this.curX = e.x;
+                this.curY = e.y;
+                this.dist = off.norm();
+                updateBasedOnOffset(c, off);
+                c.update();
+                } else if (e.event.button = 2){ // Right click - transpose
+		    var tscale = 1.0*off.norm()/512.;
+		    var move_up = c.up.scale(-(e.y-this.curY)*tscale);
+		    var move_over = horiz.scale(-(e.x-this.curX)*tscale);
+                c.position.$add(move_up);
+                c.position.$add(move_over);
+                c.target.$add(move_up);
+                c.target.$add(move_over);
+                // Update current positions
+                this.curX = e.x;
+                this.curY = e.y;
+                c.update();
+                }
+    
+            },
+                onMouseWheel: function(e){
+                e.stop();
+                var offset = PhiloGL.Vec3.scale(camGetOffset(this.camera),
+                                1.0 - e.wheel/10.);
+                updateBasedOnOffset(this.camera, offset);
+                this.camera.update();
+            }
+            },
+            onError: function() {
+            alert("An error ocurred while loading the application");
+            },
+            onLoad: function(app) {
+            var gl = app.gl,
+                canvas = app.canvas,
+                program = app.program,
+                scene = app.scene,
+                camera = app.camera;
+
+	    gl.viewport(0, 0, canvas.width, canvas.height);
+	    gl.clearColor(0, 0, 0, 1);
+	    gl.clearDepth(1);
+	    gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
+	    gl.enable(gl.BLEND);
+	    gl.disable(gl.DEPTH_TEST);
+	    program.setUniform('alpha', 0.8);
+
+	    program.setBuffers({
+
+		    'shapeset': {
+			attribute: 'aVertexPosition',
+			    value: new Float32Array(widget_data['stream_positions']),
+			    size: 3
+			    },
+			
+			'shapesetColors': {
+			    attribute: 'aVertexColor',
+				value: new Float32Array(widget_data['stream_colors']),
+				size: 4
+			    },
+			    });
+
+
+	    camera.view.id();
+	    setInterval(draw, 30/60);
+	    var stream_counter =0;
+	    //Draw the scene
+	    function draw() {
+		stream_counter = 0;
+		gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+		//Draw Triangle
+		program.setUniform('uMVMatrix', camera.view);
+		program.setUniform('uPMatrix', camera.projection);
+		program.setBuffer('shapeset');
+		program.setBuffer('shapesetColors');
+		for (var i=0; i<widget_data['n_streamlines']; i++){
+		    gl.drawArrays(gl.LINES, stream_counter, widget_data['stream_lengths'][i]-1);
+		    gl.drawArrays(gl.LINES, stream_counter+1, widget_data['stream_lengths'][i]-1);
+		    stream_counter += widget_data['stream_lengths'][i];
+		}
+		
+	    }
+	    }
+        });  
+    }        
+
+    viewport.get("center-panel").add(
+        {
+            xtype: 'panel',
+            id: "sl_" + python_varname,
+            title: "WebGL Streamline Viewer",
+            iconCls: 'graph',
+            autoScroll: true,
+            layout:'absolute',
+            closable: true,
+            items: [
+                { xtype:'panel',
+                  autoEl: {
+                    tag: 'canvas',
+                    id: 'canvas_' + python_varname,
+                    style: 'border: none;',
+                    width: 512, height:512
+                  },
+                  width: 512,
+                  height: 512
+                }],
+            listeners: { afterlayout: StreamlineViewerStart },
+        }
+    );
+
+    viewport.get("center-panel").activate("sl_" + this.id);
+    viewport.doLayout();
+    this.panel = viewport.get("center-panel").get("sl_" + python_varname);
+    this.panel.doLayout();
+
+    this.accept_results = function(payload) { }
+}
+
+widget_types['streamline_viewer'] = WidgetStreamlineViewer;


diff -r 47094c9542e2ad48b54789108882ddcf8faf9285 -r 62ef095a290cc6041ee9cb44794535b8884b2e0f yt/gui/reason/html/js/widget_griddata.js
--- a/yt/gui/reason/html/js/widget_griddata.js
+++ /dev/null
@@ -1,146 +0,0 @@
-/**********************************************************************
-The Plot Window Widget
-
-Author: Matthew Turk <matthewturk at gmail.com>
-Affiliation: Columbia University
-Homepage: http://yt-project.org/
-License:
-  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
-
-  This file is part of yt.
-
-  yt is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 3 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-***********************************************************************/
-
-// shim layer with setTimeout fallback
-var WidgetGridDataViewer = function(python_varname, widget_data) {
-    this.id = python_varname;
-    this.widget_data = widget_data;
-    store = new Ext.data.ArrayStore({
-        fields: [
-           {name: 'grid_id', type:'int'},
-           {name: 'level', type:'int'},
-           {name: 'left_edge_x', type: 'float'},
-           {name: 'left_edge_y', type: 'float'},
-           {name: 'left_edge_z', type: 'float'},
-           {name: 'right_edge_x', type: 'float'},
-           {name: 'right_edge_y', type: 'float'},
-           {name: 'right_edge_z', type: 'float'},
-           {name: 'dim_x', type: 'int'},
-           {name: 'dim_y', type: 'int'},
-           {name: 'dim_z', type: 'int'},
-           {name: 'cells', type: 'int'},
-        ]
-    });
-    store.loadData(widget_data['gridvals']);
-    examine = widget_data;
-
-    viewport.get("center-panel").add(
-        {
-            xtype: 'panel',
-            id: "gg_" + python_varname,
-            title: "Grid Data Viewer",
-            iconCls: 'graph',
-            autoScroll: true,
-            layout:'vbox',
-            layoutConfig: {align: 'stretch', pack: 'start'},
-            closable: true,
-            items: [ {
-                       xtype: 'grid',
-                       store: store,
-                       columns: [
-                            {
-                                id: 'grid_id',
-                                header: 'Grid ID',
-                                width: 100,
-                                dataIndex: 'grid_id',
-                                sortable: true,
-                            }, {
-                                id: 'left_edge_x',
-                                header: 'Left Edge x',
-                                width: 100,
-                                dataIndex: 'left_edge_x',
-                                sortable: true,
-                            }, {
-                                id: 'left_edge_y',
-                                header: 'Left Edge y',
-                                width: 100,
-                                dataIndex: 'left_edge_y',
-                                sortable: true,
-                            }, {
-                                id: 'left_edge_z',
-                                header: 'Left Edge z',
-                                width: 100,
-                                dataIndex: 'left_edge_z',
-                                sortable: true,
-                            }, {
-                                id: 'right_edge_x',
-                                header: 'Right Edge x',
-                                width: 100,
-                                dataIndex: 'right_edge_x',
-                                sortable: true,
-                            }, {
-                                id: 'right_edge_y',
-                                header: 'Right Edge y',
-                                width: 100,
-                                dataIndex: 'right_edge_y',
-                                sortable: true,
-                            }, {
-                                id: 'right_edge_z',
-                                header: 'Right Edge z',
-                                width: 100,
-                                dataIndex: 'right_edge_z',
-                                sortable: true,
-                            }, {
-                                id: 'dim_x',
-                                header: 'DimX',
-                                width: 100,
-                                dataIndex: 'dim_x',
-                                sortable: true,
-                            }, {
-                                id: 'dim_y',
-                                header: 'DimY',
-                                width: 100,
-                                dataIndex: 'dim_y',
-                                sortable: true,
-                            }, {
-                                id: 'dim_z',
-                                header: 'DimZ',
-                                width: 100,
-                                dataIndex: 'dim_z',
-                                sortable: true,
-                            }, {
-                                id: 'cells',
-                                header: 'Cells',
-                                width: 100,
-                                dataIndex: 'cells',
-                                sortable: true,
-                            },
-                       ],
-                      flex: 1,
-                      }
-                   ],
-
-        }
-    );
-
-    viewport.get("center-panel").activate("gg_" + this.id);
-    viewport.doLayout();
-    this.panel = viewport.get("center-panel").get("gg_" + python_varname);
-    this.panel.doLayout();
-
-    this.accept_results = function(payload) { }
-}
-
-widget_types['grid_data'] = WidgetGridDataViewer;


diff -r 47094c9542e2ad48b54789108882ddcf8faf9285 -r 62ef095a290cc6041ee9cb44794535b8884b2e0f yt/gui/reason/html/js/widget_gridviewer.js
--- a/yt/gui/reason/html/js/widget_gridviewer.js
+++ /dev/null
@@ -1,211 +0,0 @@
-/**********************************************************************
-The Plot Window Widget
-
-Author: Samuel Skillman <samskillman at gmail.com>
-Affiliation: University of Colorado at Boulder
-Author: Matthew Turk <matthewturk at gmail.com>
-Affiliation: Columbia University
-Homepage: http://yt-project.org/
-License:
-  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
-
-  This file is part of yt.
-
-  yt is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 3 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-***********************************************************************/
-
-// shim layer with setTimeout fallback
-window.requestAnimFrame = (function(){
-    return  window.requestAnimationFrame       || 
-        window.webkitRequestAnimationFrame || 
-        window.mozRequestAnimationFrame    || 
-        window.oRequestAnimationFrame      || 
-        window.msRequestAnimationFrame     || 
-        function(/* function */ callback, /* DOMElement */ element){
-            window.setTimeout(callback, 1000 / 60);
-        };
-})();
-
-var WidgetGridViewer = function(python_varname, widget_data) {
-    this.id = python_varname;
-    this.widget_data = widget_data;
-    examine = "canvas_" + python_varname;
-    var draw;
-    var GridViewerStart = function() {
-        this.curX = 0;
-        this.curY = 0;
-        this.dist = 0;
-        function updateBasedOnOffset(camera, offset){
-            camera.position.x = camera.target.x + offset.x;
-            camera.position.y = camera.target.y + offset.y;
-            camera.position.z = camera.target.z + offset.z;
-            draw();
-        }
-        function camGetOffset(camera){
-            return PhiloGL.Vec3.sub(camera.position, camera.target)
-        }
-        PhiloGL('canvas_' + python_varname, {
-            camera: {
-		position: {
-                    x: 0.5, y: 0.5, z: 5
-		},
-                target: {
-                    x: 0.5, y: 0.5, z: 0.5
-                },
-            },
-            events: {
-		onDragStart: function(e) {
-                    pos = {
-			x: e.x,
-			y: e.y
-                    };
-                    this.curX = e.x;
-                    this.curY = e.y;
-                    this.dist = camGetOffset(this.camera).norm();
-		},
-                onDragEnd: function(e) {
-                    pos = {
-			x: e.x,
-			y: e.y
-                    };
-  		},
-                onDragMove: function(e) {
-                    var c = this.camera;
-                    var off = camGetOffset(c);
-
-                    // Get Horizontal vector
-                    var horiz = PhiloGL.Vec3.cross(c.up, 
-						   camGetOffset(c))
-                    horiz.$scale(1./horiz.norm());
-
-                    if (e.event.button == 0){ // Rotation
-			// Do vertical rotation about horizontal vector
-			var vert_rot = new PhiloGL.Mat4();
-			vert_rot.id();
-			vert_rot.$rotateAxis((e.y-this.curY)/100., horiz);
-			PhiloGL.Mat4.$mulVec3(vert_rot, off);
-			PhiloGL.Mat4.$mulVec3(vert_rot, c.up);
-			c.up.$scale(1./c.up.norm());
-
-			// Do horizontal rotation about up vector
-			var side_rot = new PhiloGL.Mat4();
-			side_rot.id();
-			side_rot.$rotateAxis(-(e.x-this.curX)/100., c.up);
-			side_rot.$mulVec3(off);
-			
-			// Update current positions
-			this.curX = e.x;
-			this.curY = e.y;
-			this.dist = off.norm();
-			updateBasedOnOffset(c, off);
-			this.camera.near = this.dist/100000.0;
-			this.camera.far = this.dist*2.0;
-			c.update();
-                    } else if (e.event.button = 2){ // Right click - transpose
-			var tscale = 1.0*off.norm()/512.;
-			var move_up = c.up.scale(-(e.y-this.curY)*tscale);
-			var move_over = horiz.scale(-(e.x-this.curX)*tscale);
-			c.position.$add(move_up);
-			c.position.$add(move_over);
-			c.target.$add(move_up);
-			c.target.$add(move_over);
-			// Update current positions
-			this.curX = e.x;
-			this.curY = e.y;
-			this.dist = off.norm();
-			this.camera.near = this.dist/100000.0;
-			this.camera.far = this.dist*2.0;
-			c.update();
-                    }
-		    draw();
-		},
-                onMouseWheel: function(e){
-                    e.stop();
-                    var offset = PhiloGL.Vec3.scale(camGetOffset(this.camera),
-						    1.0 - e.wheel/10.);
-                    updateBasedOnOffset(this.camera, offset);
-		    var dist = offset.norm()
-                    this.camera.near = offset.norm()/100000.0;
-                    this.camera.far = offset.norm()*2.0;
-                    this.camera.update();
-                    draw();
-		}
-            },
-            onError: function() {
-		alert("An error ocurred while loading the application");
-            },
-            onLoad: function(app) {
-		var gl = app.gl,
-                canvas = app.canvas,
-                program = app.program,
-                scene = app.scene,
-                camera = app.camera;
-		var grids = new PhiloGL.O3D.Model({
-            vertices : widget_data['vertex_positions'],
-            drawType : "LINES",
-            colors : widget_data['vertex_colors'],
-        });
-        scene.add(grids);
-		gl.viewport(0, 0, canvas.width, canvas.height);
-		gl.clearColor(0, 0, 0, 1);
-
-		//examine = camera;
-		camera.view.id();
-		camera.update();
-		
-		//Draw the scene
-		draw = function() {
-	    	    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
-                scene.render();
-		}
-
-		draw();
-
-	    }
-        });  
-    }        
-
-    viewport.get("center-panel").add(
-        {
-            xtype: 'panel',
-            id: "gv_" + python_varname,
-            title: "WebGL Grid Viewer",
-            iconCls: 'graph',
-            autoScroll: true,
-            layout:'absolute',
-            closable: true,
-            items: [
-                { xtype:'panel',
-                  autoEl: {
-                      tag: 'canvas',
-                      id: 'canvas_' + python_varname,
-                      style: 'border: none;',
-                      width: 512, height:512
-                  },
-                  width: 512,
-                  height: 512
-                }],
-            listeners: { afterlayout: GridViewerStart },
-        }
-    );
-
-    viewport.get("center-panel").activate("gv_" + this.id);
-    viewport.doLayout();
-    this.panel = viewport.get("center-panel").get("gv_" + python_varname);
-    this.panel.doLayout();
-
-    this.accept_results = function(payload) { }
-}
-
-widget_types['grid_viewer'] = WidgetGridViewer;


diff -r 47094c9542e2ad48b54789108882ddcf8faf9285 -r 62ef095a290cc6041ee9cb44794535b8884b2e0f yt/gui/reason/html/js/widget_isocontour.js
--- a/yt/gui/reason/html/js/widget_isocontour.js
+++ /dev/null
@@ -1,213 +0,0 @@
-/**********************************************************************
-The isocontour viewer widget
-
-Author: Samuel Skillman <samskillman at gmail.com>
-Affiliation: University of Colorado at Boulder
-Author: Matthew Turk <matthewturk at gmail.com>
-Affiliation: Columbia University
-Homepage: http://yt-project.org/
-License:
-  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
-
-  This file is part of yt.
-
-  yt is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 3 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-***********************************************************************/
-
-// shim layer with setTimeout fallback
-window.requestAnimFrame = (function(){
-    return  window.requestAnimationFrame       || 
-        window.webkitRequestAnimationFrame || 
-        window.mozRequestAnimationFrame    || 
-        window.oRequestAnimationFrame      || 
-        window.msRequestAnimationFrame     || 
-        function(/* function */ callback, /* DOMElement */ element){
-            window.setTimeout(callback, 1000 / 60);
-        };
-})();
-
-var exagain;
-var WidgetIsocontourViewer = function(python_varname, widget_data) {
-    this.id = python_varname;
-    this.widget_data = widget_data;
-    examine = "canvas_" + python_varname;
-    var draw;
-    var GridViewerStart = function() {
-        this.curX = 0;
-        this.curY = 0;
-        this.dist = 0;
-        function updateBasedOnOffset(camera, offset){
-            camera.position.x = camera.target.x + offset.x;
-            camera.position.y = camera.target.y + offset.y;
-            camera.position.z = camera.target.z + offset.z;
-            draw();
-        }
-        function camGetOffset(camera){
-            return PhiloGL.Vec3.sub(camera.position, camera.target)
-        }
-        PhiloGL('canvas_' + python_varname, {
-            camera: {
-		position: {
-                    x: 0.5, y: 0.5, z: 5
-		},
-                target: {
-                    x: 0.5, y: 0.5, z: 0.5
-                },
-            },
-            events: {
-		onDragStart: function(e) {
-                    pos = {
-			x: e.x,
-			y: e.y
-                    };
-                    this.curX = e.x;
-                    this.curY = e.y;
-                    this.dist = camGetOffset(this.camera).norm();
-		},
-                onDragEnd: function(e) {
-                    pos = {
-			x: e.x,
-			y: e.y
-                    };
-  		},
-                onDragMove: function(e) {
-                    var c = this.camera;
-                    var off = camGetOffset(c);
-
-                    // Get Horizontal vector
-                    var horiz = PhiloGL.Vec3.cross(c.up, 
-						   camGetOffset(c))
-                    horiz.$scale(1./horiz.norm());
-
-                    if (e.event.button == 0){ // Rotation
-			// Do vertical rotation about horizontal vector
-			var vert_rot = new PhiloGL.Mat4();
-			vert_rot.id();
-			vert_rot.$rotateAxis((e.y-this.curY)/100., horiz);
-			PhiloGL.Mat4.$mulVec3(vert_rot, off);
-			PhiloGL.Mat4.$mulVec3(vert_rot, c.up);
-			c.up.$scale(1./c.up.norm());
-
-			// Do horizontal rotation about up vector
-			var side_rot = new PhiloGL.Mat4();
-			side_rot.id();
-			side_rot.$rotateAxis(-(e.x-this.curX)/100., c.up);
-			side_rot.$mulVec3(off);
-			
-			// Update current positions
-			this.curX = e.x;
-			this.curY = e.y;
-			this.dist = off.norm();
-			updateBasedOnOffset(c, off);
-			this.camera.near = this.dist/100000.0;
-			this.camera.far = this.dist*2.0;
-			c.update();
-                    } else if (e.event.button = 2){ // Right click - transpose
-			var tscale = 1.0*off.norm()/512.;
-			var move_up = c.up.scale(-(e.y-this.curY)*tscale);
-			var move_over = horiz.scale(-(e.x-this.curX)*tscale);
-			c.position.$add(move_up);
-			c.position.$add(move_over);
-			c.target.$add(move_up);
-			c.target.$add(move_over);
-			// Update current positions
-			this.curX = e.x;
-			this.curY = e.y;
-			this.dist = off.norm();
-			this.camera.near = this.dist/100000.0;
-			this.camera.far = this.dist*2.0;
-			c.update();
-                    }
-		    draw();
-		},
-                onMouseWheel: function(e){
-                    e.stop();
-                    var offset = PhiloGL.Vec3.scale(camGetOffset(this.camera),
-						    1.0 - e.wheel/10.);
-                    updateBasedOnOffset(this.camera, offset);
-		    var dist = offset.norm()
-                    this.camera.near = offset.norm()/100000.0;
-                    this.camera.far = offset.norm()*2.0;
-                    this.camera.update();
-                    draw();
-		}
-            },
-            onError: function() {
-		alert("An error ocurred while loading the application");
-            },
-            onLoad: function(app) {
-		var gl = app.gl,
-                canvas = app.canvas,
-                program = app.program,
-                scene = app.scene,
-                camera = app.camera;
-		var grids = new PhiloGL.O3D.Model({
-            vertices : widget_data['vertex_positions'],
-            drawType : "TRIANGLES",
-            colors : widget_data['vertex_colors'],
-        });
-        exagain = grids;
-        scene.add(grids);
-		gl.viewport(0, 0, canvas.width, canvas.height);
-		gl.clearColor(0, 0, 0, 1);
-
-		//examine = camera;
-		camera.view.id();
-		camera.update();
-		
-		//Draw the scene
-		draw = function() {
-	    	    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
-                scene.render();
-		}
-
-		draw();
-
-	    }
-        });  
-    }        
-
-    viewport.get("center-panel").add(
-        {
-            xtype: 'panel',
-            id: "iv_" + python_varname,
-            title: "WebGL Isocontour Viewer",
-            iconCls: 'graph',
-            autoScroll: true,
-            layout:'absolute',
-            closable: true,
-            items: [
-                { xtype:'panel',
-                  autoEl: {
-                      tag: 'canvas',
-                      id: 'canvas_' + python_varname,
-                      style: 'border: none;',
-                      width: 512, height:512
-                  },
-                  width: 512,
-                  height: 512
-                }],
-            listeners: { afterlayout: GridViewerStart },
-        }
-    );
-
-    viewport.get("center-panel").activate("iv_" + this.id);
-    viewport.doLayout();
-    this.panel = viewport.get("center-panel").get("iv_" + python_varname);
-    this.panel.doLayout();
-
-    this.accept_results = function(payload) { }
-}
-
-widget_types['isocontour_viewer'] = WidgetIsocontourViewer;


diff -r 47094c9542e2ad48b54789108882ddcf8faf9285 -r 62ef095a290cc6041ee9cb44794535b8884b2e0f yt/gui/reason/html/js/widget_pannablemap.js
--- a/yt/gui/reason/html/js/widget_pannablemap.js
+++ /dev/null
@@ -1,76 +0,0 @@
-/**********************************************************************
-The Pannable Map Widget
-
-Author: Matthew Turk <matthewturk at gmail.com>
-Affiliation: Columbia University
-Homepage: http://yt-project.org/
-License:
-  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
-
-  This file is part of yt.
-
-  yt is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 3 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-***********************************************************************/
-
-var WidgetPannableMap = function(python_varname, widget_data) {
-    this.id = python_varname;
-    this.widget_data = widget_data;
-
-    viewport.get("center-panel").add(
-        {
-            xtype: 'panel',
-            id: "pm_" + this.id,
-            title: "Pannable Map",
-            iconCls: 'graph',
-            autoScroll: true,
-            layout:'absolute',
-            closable: true,
-            items: [ 
-                {
-                    xtype:'box',
-                    autoEl: {
-                        tag: 'div',
-                        id: "map_" + this.id,
-                        width: 512,
-                        height: 512,
-                    },
-                    x: 10,
-                    y: 10,
-                    width: 512,
-                    height: 512,
-                    listeners: {afterrender:
-                        function() {
-                          var map = new L.Map('map_' + python_varname, {
-                                  center: new L.LatLng(0.0, 0.0),
-                                  zoom: 0,
-                                  });
-                          var cloudmadeUrl = widget_data['prefix'] + '/map/{z}/{x}/{y}.png';
-                          cloudmade = new L.TileLayer(cloudmadeUrl, {maxZoom: 18});
-                          map.addLayer(cloudmade);
-                    }},
-                }  
-            ]
-        }
-    );
-
-    viewport.get("center-panel").activate("pm_" + this.id);
-    viewport.doLayout();
-    this.panel = viewport.get("center-panel").get("pm_" + this.id);
-    this.panel.doLayout();
-    examine = this.panel;
-
-    this.accept_results = function(payload) { }
-}
-
-widget_types['pannable_map'] = WidgetPannableMap;


diff -r 47094c9542e2ad48b54789108882ddcf8faf9285 -r 62ef095a290cc6041ee9cb44794535b8884b2e0f yt/gui/reason/html/js/widget_phaseplot.js
--- a/yt/gui/reason/html/js/widget_phaseplot.js
+++ /dev/null
@@ -1,239 +0,0 @@
-/**********************************************************************
-The Plot Window Widget
-
-Author: Matthew Turk <matthewturk at gmail.com>
-Affiliation: Columbia University
-Homepage: http://yt-project.org/
-License:
-  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
-
-  This file is part of yt.
-
-  yt is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 3 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-***********************************************************************/
-
-
-
-var WidgetPhasePlot = function(python_varname, widget_data) {
-    this.id = python_varname;
-    this.widget_data = widget_data;
-
-    viewport.get("center-panel").add(
-        {
-            xtype: 'panel',
-            id: "pp_" + this.id,
-            title: widget_data['title'],
-            iconCls: 'graph',
-            autoScroll: true,
-            layout:'absolute',
-            closable: true,
-            items: [ 
-                {
-                    xtype: 'panel',
-                    id: 'y_ticks_' + python_varname,
-                    layout: 'absolute',
-                    y: 10,
-                    x: 100,
-                    width: 40,
-                    height: 400,
-                    items : [],
-                    border: false,
-                }, {
-                    xtype: 'panel',
-                    id: 'x_ticks_' + python_varname,
-                    layout: 'absolute',
-                    y: 410,
-                    x: 140,
-                    width: 400,
-                    height: 40,
-                    items : [],
-                    border: false,
-                }, {
-                    xtype:'panel',
-                    id: 'image_panel_' + this.id,
-                    autoEl: {
-                        tag: 'img',
-                        id: "img_" + this.id,
-                        width: 400,
-                        height: 400,
-                        style: 'border: 1px solid #000000',
-                    },
-                    x: 138,
-                    y: 8,
-                    width: 400,
-                    height: 400,
-                }, {
-                    xtype:'panel',
-                    id: 'colorbar_' + python_varname,
-                    autoEl: {
-                        tag: 'img',
-                        id: "cb_" + python_varname,
-                        src: "data:image/png;base64," +
-                             widget_data['colorbar'],
-                        width: 28,
-                        height: 398,
-                        style: 'border: 1px solid #000000;',
-                    },
-                    x: 560,
-                    y: 10,
-                    width: 30,
-                    height: 400,
-                }, {
-                    xtype: 'panel',
-                    id: 'ticks_' + python_varname,
-                    layout: 'absolute',
-                    y: 10,
-                    x: 590,
-                    width: 40,
-                    height: 400,
-                    items : [],
-                    border: false,
-                },{
-                    xtype: 'button',
-                    text: 'Upload Image',
-                    x: 10,
-                    y: 285,
-                    width: 80,
-                    tooltip: "Upload the current image to " +
-                             "<a href='http://imgur.com'>imgur.com</a>",
-                    handler: function(b,e) {
-                        img_data = image_dom.src;
-                        yt_rpc.ExtDirectREPL.upload_image(
-                            {image_data:img_data,
-                             caption:metadata_string},
-                        function(rv) {
-                            var alert_text;
-                            if(rv['uploaded'] == false) {
-                                alert_text = "Failure uploading image!";
-                            } else {
-                                alert_text = "Uploaded to " +
-                                        rv['upload']['links']['imgur_page'];
-                            }
-                            Ext.Msg.alert('imgur.com', alert_text);
-                            var record = new logging_store.recordType(
-                                {record: alert_text });
-                            logging_store.add(record, number_log_records++);
-                        }); 
-                    }
-                },{
-                    xtype: 'panel',
-                    layout: 'vbox',
-                    id: 'rhs_panel_' + python_varname,
-                    width: 300,
-                    height: 460,
-                    x: 640, y: 10,
-                    layoutConfig: {
-                        align: 'stretch',
-                        pack: 'start',
-                    },
-                    items: [
-                        {
-                          xtype: 'panel',
-                          title: 'Plot MetaData',
-                          id: 'metadata_' + python_varname,
-                          style: {fontFamily: '"Inconsolata", monospace'},
-                          html: 'Welcome to the Plot Window.',
-                          height: 200,
-                        }, {
-                          xtype: 'panel',
-                          title: 'Plot Editor',
-                          id: 'plot_edit',
-                          flex: 1,
-                        }]
-                }
-            ]
-        }
-    );
-
-    viewport.get("center-panel").activate("pp_" + this.id);
-    viewport.get("center-panel").doLayout();
-    viewport.doLayout();
-    this.panel = viewport.get("center-panel").get("pp_" + python_varname);
-    this.panel.doLayout();
-    this.panel.show();
-    this.image_panel = this.panel.get("image_panel_"+python_varname);
-    this.ticks = this.panel.get("ticks_"+python_varname);
-    var x_ticks = this.panel.get("x_ticks_"+python_varname);
-    var y_ticks = this.panel.get("y_ticks_"+python_varname);
-    var ticks = this.ticks;
-    this.metadata_panel = this.panel.get("rhs_panel_" + python_varname).get("metadata_" + python_varname);
-    var image_dom = this.image_panel.el.dom;
-    var control_panel = this.panel;
-    var metadata_string;
-    var colorbar = this.panel.get("colorbar_"+python_varname);
-
-    this.accept_results = function(payload) {
-        this.image_panel.el.dom.src = "data:image/png;base64," + payload['image_data'];
-        examine = this.metadata_panel;
-        this.metadata_panel.update(payload['metadata_string']);
-        metadata_string = payload['metadata_string'];
-        ticks.removeAll();
-        colorbar.el.dom.src = "data:image/png;base64," +
-                              payload['cbar']['cmap_image'];
-        Ext.each(payload['yax']['ticks'], function(tick, index) {
-            examine = tick;
-            y_ticks.add({xtype:'panel',
-                       width: 20, height:15,
-                       border: false,
-                       style: 'font-family: "Inconsolata", monospace;' +
-                              'font-size: 12px; text-align: right;' +
-                              'padding-right: 5px;',
-                       html: ' ' + tick[2] + ' ',
-                       x:0, y: tick[0]-6});
-            y_ticks.add({xtype:'panel',
-                       width: 20, height:1,
-                       style: 'background-color: #000000;',
-                       html:' ',
-                       x:20, y: tick[0]});
-        });
-        y_ticks.doLayout();
-        Ext.each(payload['xax']['ticks'], function(tick, index) {
-            examine = tick;
-            x_ticks.add({xtype:'panel',
-                       width: 1, height:20,
-                       style: 'background-color: #000000;',
-                       html:' ',
-                       x:(400 - tick[0]) + 10, y: 0});
-            x_ticks.add({xtype:'panel',
-                       width: 20, height:20,
-                       border: false,
-                       style: 'font-family: "Inconsolata", monospace;' +
-                              'font-size: 12px; text-align: center;',
-                       html: ' ' + tick[2] + ' ',
-                       x: (400 - tick[0]), y: 20});
-        });
-        x_ticks.doLayout();
-        Ext.each(payload['cbar']['ticks'], function(tick, index) {
-            ticks.add({xtype:'panel',
-                       width: 10, height:1,
-                       style: 'background-color: #000000;',
-                       html:' ',
-                       x:0, y: tick[0]});
-            ticks.add({xtype:'panel',
-                       width: 30, height:15,
-                       border: false,
-                       style: 'font-family: "Inconsolata", monospace;' +
-                              'font-size: 12px;',
-                       html: ' ' + tick[2] + ' ',
-                       x:18, y: tick[0]-6});
-        });
-        ticks.doLayout();
-        x_ticks.doLayout();
-    }
-    yt_rpc.ExtDirectREPL.execute(
-        {code:python_varname + '._setup_plot()', hide:true},
-        cell_finished);
-}
-
-widget_types['phase_plot'] = WidgetPhasePlot;


diff -r 47094c9542e2ad48b54789108882ddcf8faf9285 -r 62ef095a290cc6041ee9cb44794535b8884b2e0f yt/gui/reason/html/js/widget_plotwindow.js
--- a/yt/gui/reason/html/js/widget_plotwindow.js
+++ /dev/null
@@ -1,732 +0,0 @@
-/**********************************************************************
-The Plot Window Widget
-
-Author: Cameron Hummels <chummels at gmail.com>
-Affiliation: Columbia
-Author: Jeffrey S. Oishi <jsoishi at gmail.com>
-Affiliation: KIPAC/SLAC/Stanford
-Author: Britton Smith <brittonsmith at gmail.com>
-Affiliation: MSU
-Author: Matthew Turk <matthewturk at gmail.com>
-Affiliation: Columbia University
-Homepage: http://yt-project.org/
-License:
-  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
-
-  This file is part of yt.
-
-  yt is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 3 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-***********************************************************************/
-
-
-
-var WidgetPlotWindow = function(python_varname, widget_data) {
-    this.id = python_varname;
-    this.widget_data = widget_data;
-    this.print_python = function(b, e) {
-        yt_rpc.ExtDirectREPL.execute(
-            {code:'print "' + python_varname + '"',
-             hide:true},
-            function(f, a) {alert(a.result['output']);}
-        );
-    }
-
-    this.widget_keys = new Ext.KeyMap(document, [
-        {key: 'z',
-         shift: false,
-         fn: function(){
-               control_panel.get("zoom2x").handler();
-            }
-        },
-        {key: 'Z',
-         shift: true,
-         fn: function(){
-               control_panel.get("zoom10x").handler();
-            }
-        },
-        {key: 'x',
-         shift: false,
-         fn: function(){
-               control_panel.get("zoomout2x").handler();
-            }
-        },
-        {key: 'X',
-         shift: true,
-         fn: function(){
-               control_panel.get("zoomout10x").handler();
-            }
-        },
-        {key: 'k',
-         shift: false,
-         fn: function(){
-               control_panel.get("singleuparrow").handler();
-            }
-        },
-        {key: 'j',
-         shift: false,
-         fn: function(){
-               control_panel.get("singledownarrow").handler();
-            }
-        },
-        {key: 'h',
-         shift: false,
-         fn: function(){
-               control_panel.get("singleleftarrow").handler();
-            }
-        },
-        {key: 'l',
-         shift: false,
-         fn: function(){
-               control_panel.get("singlerightarrow").handler();
-            }
-        },
-        {key: 'K',
-         shift: true,
-         fn: function(){
-               control_panel.get("doubleuparrow").handler();
-            }
-        },
-        {key: 'J',
-         shift: true,
-         fn: function(){
-               control_panel.get("doubledownarrow").handler();
-            }
-        },
-        {key: 'H',
-         shift: true,
-         fn: function(){
-               control_panel.get("doubleleftarrow").handler();
-            }
-        },
-        {key: 'L',
-         shift: true,
-         fn: function(){
-               control_panel.get("doublerightarrow").handler();
-            }
-        },
-    ]);
-    var widget_keys = this.widget_keys;
-    widget_keys.disable();
-    widget_keys.varname = python_varname;
-
-    viewport.get("center-panel").add(
-        {
-            xtype: 'panel',
-            id: "pw_" + this.id,
-            title: widget_data['title'],
-            iconCls: 'graph',
-            autoScroll: true,
-            layout:'absolute',
-            closable: true,
-            listeners: {activate: function(p){
-                                widget_keys.enable();
-                            },
-                        deactivate: function(p){
-                                widget_keys.disable();
-                            }
-                        },
-            items: [ 
-                {
-                    xtype:'panel',
-                    id: 'image_panel_' + this.id,
-                    autoEl: {
-                        tag: 'img',
-                        id: "img_" + this.id,
-                        width: 400,
-                        height: 400,
-                        draggable: false,
-                    },
-                    x: 100,
-                    y: 10,
-                    width: 400,
-                    height: 400,
-                    draggable: false,
-                    listeners: {
-                        afterrender: function(c){
-                            c.el.on('click', function(e){
-                                if (e.ctrlKey == false) return;
-                                xy = e.getXY();
-                                cc = python_varname + ".image_recenter(" 
-                                    + (xy[0] - c.el.dom.x) + ", "
-                                    + (xy[1] - c.el.dom.y) + ", "
-                                    + c.el.dom.width + ", "
-                                    + c.el.dom.height + ")";
-                                yt_rpc.ExtDirectREPL.execute(
-                                {code:cc, hide:true}, cell_finished); 
-                            });
-                            c.el.on('mousedown', function(e){
-                                c.drag_start = true;
-                                c.drag_start_pos = e.getXY();
-                            });
-                            c.el.on('mouseup', function(e){
-                                c.drag_start = false;
-                                drag_stop = e.getXY();
-                                delta_x = drag_stop[0] - c.drag_start_pos[0];
-                                delta_y = drag_stop[1] - c.drag_start_pos[1];
-                                if (((delta_x < -10) || (delta_x > 10)) ||
-                                    ((delta_y < -10) || (delta_y > 10))) {
-                                    rel_x = -delta_x / 400;
-                                    rel_y = -delta_y / 400;
-                                    cc = python_varname + '.pan_rel((' + 
-                                        rel_x + ',' + rel_y + '))';
-                                    yt_rpc.ExtDirectREPL.execute(
-                                    {code:cc, hide:true}, cell_finished); 
-                                }
-                            });
-                        }
-                    }
-                }, {
-                    xtype:'panel',
-                    id: 'colorbar_' + python_varname,
-                    autoEl: {
-                        tag: 'img',
-                        id: "cb_" + python_varname,
-                        src: "data:image/png;base64," +
-                             widget_data['colorbar'],
-                        width: 28,
-                        height: 398,
-                        style: 'border: 1px solid #000000;',
-                    },
-                    x: 510,
-                    y: 10,
-                    width: 30,
-                    height: 400,
-                }, {
-                    xtype: 'panel',
-                    id: 'ticks_' + python_varname,
-                    layout: 'absolute',
-                    y: 0,
-                    x: 540,
-                    width: 100,
-                    height: 420,
-                    items : [],
-                    border: false,
-                }, {   xtype: 'multislider',
-                    id: 'slider_' + python_varname,
-                    minValue: 0,
-                    maxValue: 100,
-                    increment: 0.1,
-                    x: 100, y: 410,
-                    width: 400,
-                    listeners: {
-                        /* Only changecomplete; don't want too many render
-                        events */
-                        changecomplete: function(slider, newValue, thumb) {
-                            yt_rpc.ExtDirectREPL.execute(
-                                {code:python_varname + ".scroll_zoom(" +
-                                      newValue + ")",
-                                 hide:true}, cell_finished);
-                        }
-                    }
-                },{
-                    xtype: 'combo',
-                    text: 'Field',
-                    x: 100,
-                    y: 435,
-                    width: 400,
-                    store:widget_data['fields'],
-                    value:widget_data['initial_field'],
-                    editable: false,
-                    triggerAction: 'all',
-                    validateOnBlur: false,
-                    listeners: {select: function(combo, record, index) {
-                        var newValue = record.data['field1'];
-                        yt_rpc.ExtDirectREPL.execute(
-                            {code:python_varname + '.set_current_field("' +
-                                newValue + '")', hide:false},
-                            cell_finished);
-                    }}
-                }, {
-                /* the single buttons for 10% pan*/
-                    xtype:'button',
-                    iconCls: 'singleuparrow',
-                    id: 'singleuparrow',
-                    //text: 'North',
-                    x: 40,
-                    y: 10,
-                    handler: function(b,e) {
-                        cc = python_varname + '.pan_rel((0.0, -0.1))'
-                        yt_rpc.ExtDirectREPL.execute(
-                        {code:cc, hide:true}, cell_finished); 
-                    }
-                }, {
-                    xtype:'button',
-                    iconCls: 'singlerightarrow',
-                    id: 'singlerightarrow',
-                    //text:'East',
-                    x : 60,
-                    y : 30,
-                    handler: function(b,e) {
-                        yt_rpc.ExtDirectREPL.execute(
-                            {code:python_varname + '.pan_rel((0.1, 0.0))',
-                             hide:true},
-                        cell_finished); 
-                    }
-                }, {
-                    xtype:'button',
-                    iconCls: 'singledownarrow',
-                    id: 'singledownarrow',
-                    //text: 'South',
-                    x: 40,
-                    y: 50,
-                    handler: function(b,e) {
-                        yt_rpc.ExtDirectREPL.execute(
-                            {code:python_varname + '.pan_rel((0.0, 0.1))',
-                             hide:true},
-                        cell_finished); 
-                    }
-                }, {
-                    xtype: 'button',
-                    iconCls: 'singleleftarrow',
-                    id: 'singleleftarrow',
-                    //text: 'West',
-                    x: 20,
-                    y: 30,
-                    handler: function(b,e) {
-                        yt_rpc.ExtDirectREPL.execute(
-                            {code:python_varname + '.pan_rel((-0.1, 0.0))',
-                             hide:true},
-                        cell_finished); 
-                    }
-                }, 
-                /* the double buttons for 50% pan*/
-                {
-                    xtype:'button',
-                    iconCls: 'doubleuparrow',
-                    id:'doubleuparrow',
-                    //text: 'North',
-                    x: 40,
-                    y: 80,
-                    handler: function(b,e) {
-                        cc = python_varname + '.pan_rel((0.0, -0.5))'
-                        yt_rpc.ExtDirectREPL.execute(
-                        {code:cc, hide:true}, cell_finished); 
-                    }
-                }, {
-                    xtype:'button',
-                    iconCls: 'doublerightarrow',
-                    id:'doublerightarrow',
-                    //text:'East',
-                    x : 60,
-                    y : 100,
-                    handler: function(b,e) {
-                        yt_rpc.ExtDirectREPL.execute(
-                            {code:python_varname + '.pan_rel((0.5, 0.0))',
-                             hide:true},
-                        cell_finished); 
-                    }
-                }, {
-                    xtype:'button',
-                    iconCls: 'doubledownarrow',
-                    //text: 'South',
-                    id: 'doubledownarrow',
-                    x: 40,
-                    y: 120,
-                    handler: function(b,e) {
-                        yt_rpc.ExtDirectREPL.execute(
-                            {code:python_varname + '.pan_rel((0.0, 0.5))',
-                             hide:true},
-                        cell_finished); 
-                    }
-                }, {
-                    xtype: 'button',
-                    iconCls: 'doubleleftarrow',
-                    id: 'doubleleftarrow',
-                    //text: 'West',
-                    x: 20,
-                    y: 100,
-                    handler: function(b,e) {
-                        yt_rpc.ExtDirectREPL.execute(
-                            {code:python_varname + '.pan_rel((-0.5, 0.0))',
-                             hide:true},
-                        cell_finished); 
-                    }
-                },
-                /* Now the zoom buttons */
-                {
-                    xtype: 'button',
-                    text: 'Zoom In 10x',
-                    id: "zoom10x",
-                    x: 10,
-                    y: 160,
-                    width: 80,
-                    handler: function(b,e) {
-                        yt_rpc.ExtDirectREPL.execute(
-                            {code:python_varname + '.zoom(10.0)',
-                             hide:true},
-                        cell_finished); 
-                    }
-                },{
-                    xtype: 'button',
-                    text: 'Zoom In 2x',
-                    id: "zoom2x",
-                    x: 10,
-                    y: 185,
-                    width: 80,
-                    handler: function(b,e) {
-                        yt_rpc.ExtDirectREPL.execute(
-                            {code:python_varname + '.zoom(2.0)',
-                             hide:true},
-                        cell_finished); 
-                    }
-                },{
-                    xtype: 'button',
-                    text: 'Zoom Out 2x',
-                    id:'zoomout2x',
-                    x: 10,
-                    y: 210,
-                    width: 80,
-                    handler: function(b,e) {
-                        yt_rpc.ExtDirectREPL.execute(
-                            {code:python_varname + '.zoom(0.5)',
-                             hide:true},
-                        cell_finished); 
-                    }
-                },{
-                    xtype: 'button',
-                    text: 'Zoom Out 10x',
-                    id:'zoomout10x',
-                    x: 10,
-                    y: 235,
-                    width: 80,
-                    handler: function(b,e) {
-                        yt_rpc.ExtDirectREPL.execute(
-                            {code:python_varname + '.zoom(0.1)',
-                             hide:true},
-                        cell_finished); 
-                    }
-                },{
-                    xtype: 'button',
-                    text: 'Upload Image',
-                    x: 10,
-                    y: 285,
-                    width: 80,
-                    tooltip: "Upload the current image to " +
-                             "<a href='http://imgur.com'>imgur.com</a>",
-                    handler: function(b,e) {
-                        img_data = image_dom.src;
-                        yt_rpc.ExtDirectREPL.upload_image(
-                            {image_data:img_data,
-                             caption:metadata_string},
-                        function(rv) {
-                            var alert_text;
-                            if(rv['uploaded'] == false) {
-                                alert_text = "Failure uploading image!";
-                            } else {
-                                alert_text = "Uploaded to " +
-                                        rv['upload']['links']['imgur_page'];
-                            }
-                            Ext.Msg.alert('imgur.com', alert_text);
-                            var record = new logging_store.recordType(
-                                {record: alert_text });
-                            logging_store.add(record, number_log_records++);
-                        }); 
-                    }
-                },{
-                    xtype: 'button',
-                    text: 'Pannable Map',
-                    x: 10,
-                    y: 335,
-                    width: 80,
-                    tooltip: "Open a pannable map in a new tab",
-                    handler: function(b,e) {
-                        img_data = image_dom.src;
-                        yt_rpc.ExtDirectREPL.create_mapview(
-                            {widget_name:python_varname},
-                        function(rv) {
-                            /*alert(rv);*/
-                        }); 
-                    }
-                },{
-                    xtype: 'panel',
-                    layout: 'vbox',
-                    id: 'rhs_panel_' + python_varname,
-                    width: 250,
-                    height: 460,
-                    x: 690, y: 10,
-                    layoutConfig: {
-                        align: 'stretch',
-                        pack: 'start',
-                    },
-                    items: [
-                        {
-                          xtype: 'panel',
-                          title: 'Plot MetaData',
-                          id: 'metadata_' + python_varname,
-                          style: {fontFamily: '"Inconsolata", monospace'},
-                          html: 'Welcome to the Plot Window.',
-                          height: 200,
-                        }, {
-                          xtype: 'tabpanel',
-                          id: 'editor_panel',
-                          flex: 1,
-                          activeTab: 0,
-                          items: [
-                        {
-                          xtype: 'panel',
-                          title: 'Plot Editor',
-                          id: 'plot_edit',
-                          style: {fontFamily: '"Inconsolata", monospace'},
-                          layout: 'absolute',
-                          flex: 1,
-                          items : [
-                             {
-                               x: 10,
-                               y: 20,
-                               width: 70,
-                               xtype: 'label',
-                               text: 'Display',
-                             },
-                             {
-                               x: 80,
-                               y: 20,
-                               width : 80,
-                               xtype: 'combo',
-                               editable: false,
-                               triggerAction: 'all',
-                               validateOnBlur: false,
-                               store: ['log10', 'linear'],
-                               value: widget_data['initial_transform'],
-                               listeners: {select: function(combo, record, index){ 
-                                   var newValue = '"' + record.data['field1'] + '"';
-                                   yt_rpc.ExtDirectREPL.execute(
-                                       {code:python_varname + '.set_transform('
-                                         + python_varname + '._current_field, '
-                                         + newValue + ')', hide:false},
-                                         cell_finished);
-                               }}
-                             },
-                             {
-                               x: 10,
-                               y: 60,
-                               width: 70,
-                               xtype: 'label',
-                               text: 'Colormap',
-                             },
-                             {
-                               x: 80,
-                               y: 60,
-                               width : 140,
-                               xtype: 'combo',
-                               editable: false,
-                               triggerAction: 'all',
-                               validateOnBlur: false,
-                               store: ['algae', 'RdBu', 'gist_stern',  
-                                       'hot', 'jet', 'kamae', 
-                                        'B-W LINEAR', 'BLUE',
-                                        'GRN-RED-BLU-WHT', 'RED TEMPERATURE',
-                                        'BLUE', 'STD GAMMA-II', 'PRISM',
-                                        'RED-PURPLE', 'GREEN', 'GRN',
-                                        'GREEN-PINK', 'BLUE-RED', '16 LEVEL',
-                                        'RAINBOW', 'STEPS', 'STERN SPECIAL',
-                                        'Haze', 'Blue - Pastel - Red',
-                                        'Pastels', 'Hue Sat Lightness 1',
-                                        'Hue Sat Lightness 2', 'Hue Sat Value 1',
-                                        'Hue Sat Value 2', 'Purple-Red + Stripes',
-                                        'Beach', 'Mac Style', 'Eos A', 'Eos B',
-                                        'Hardcandy', 'Nature', 'Ocean', 'Peppermint',
-                                        'Plasma', 'Blue-Red', 'Rainbow', 'Blue Waves',
-                                        'Volcano', 'Waves', 'Rainbow18',
-                                        'Rainbow + white', 'Rainbow + black'],
-                               value: 'algae',
-                               listeners: {select: function(combo, record, index){ 
-                                   var newValue = '"' + record.data['field1'] + '"';
-                                   yt_rpc.ExtDirectREPL.execute(
-                                       {code:python_varname + '.set_cmap('
-                                         + python_varname + '._current_field, '
-                                         + newValue + ')', hide:false},
-                                         cell_finished);
-                               }}
-                             }
-                          ]
-                        }, {
-                          xtype: 'panel',
-                          title: 'Contours',
-                          id: 'contour_edit',
-                          style: {fontFamily: '"Inconsolata", monospace'},
-                          layout: 'absolute',
-                          flex: 1,
-                          items : [
-                             {
-                               x: 10,
-                               y: 20,
-                               width: 70,
-                               xtype: 'label',
-                               text: 'Field',
-                             }, {
-                               x: 80,
-                               y: 20,
-                               width : 160,
-                               xtype: 'combo',
-                               editable: false,
-                               id: 'field',
-                               triggerAction: 'all',
-                               validateOnBlur: false,
-                               value:widget_data['initial_field'],
-                               store: widget_data['fields'],
-                             }, {
-                               x: 10,
-                               y: 60,
-                               width: 70,
-                               xtype: 'label',
-                               text: 'Levels',
-                             }, {
-                               x: 80,
-                               y: 60,
-                               width : 160,
-                               xtype: 'slider',
-                               id: 'ncont',
-                               minValue: 0,
-                               maxValue: 10,
-                               value: 5,
-                               increment: 1,
-                               plugins: new Ext.slider.Tip(),
-                             }, {
-                               x: 10,
-                               y: 100,
-                               width: 70,
-                               xtype: 'label',
-                               text: 'Logspaced',
-                             }, {
-                               x: 80,
-                               y: 100,
-                               width : 160,
-                               xtype: 'checkbox',
-                               id: 'logit',
-                               checked: true,
-                             }, {
-                               x: 10,
-                               y: 180,
-                               width: 80,
-                               xtype: 'button',
-                               text: 'Apply',
-                               handler: function(b, e) {
-                                  field = contour_window.get('field').getValue();
-                                  ncont = contour_window.get('ncont').getValue();
-                                  logit = contour_window.get('logit').getValue();
-                                  if (logit == false) logit = 'False';
-                                  else if (logit == true) logit = 'True';
-                                  yt_rpc.ExtDirectREPL.execute(
-                                      {code:python_varname
-                                       + '.set_contour_info("' + field + '", '
-                                       + ncont + ', ' + logit + ')',
-                                        hide:false},
-                                      cell_finished);
-                               }
-                             }
-                          ]
-                        }, {
-                          xtype: 'panel',
-                          title: 'Velocity Vectors',
-                          id: 'vector_edit',
-                          style: {fontFamily: '"Inconsolata", monospace'},
-                          layout: 'absolute',
-                          flex: 1,
-                          items : [
-                             {
-                               x: 10,
-                               y: 60,
-                               width: 70,
-                               xtype: 'label',
-                               text: 'Skip Factor',
-                             }, {
-                               x: 80,
-                               y: 60,
-                               width : 160,
-                               xtype: 'slider',
-                               id: 'skip',
-                               minValue: 1,
-                               maxValue: 64,
-                               value: 32,
-                               increment: 1,
-                               plugins: new Ext.slider.Tip(),
-                             }, {
-                               x: 10,
-                               y: 180,
-                               width: 80,
-                               xtype: 'button',
-                               text: 'Apply',
-                               handler: function(b, e) {
-                                  skip = vector_window.get('skip').getValue();
-                                  yt_rpc.ExtDirectREPL.execute(
-                                      {code:python_varname
-                                       + '.set_vector_info('+skip+')',
-                                        hide:false},
-                                      cell_finished);
-                               }
-                             }
-                          ]
-                        }
-                        ] } /* tabpanel items and entry */
-                        ]
-                }
-            ]
-        }
-    );
-
-    viewport.get("center-panel").activate("pw_" + this.id);
-    viewport.get("center-panel").doLayout();
-    viewport.doLayout();
-    this.panel = viewport.get("center-panel").get("pw_" + python_varname);
-    this.panel.doLayout();
-    this.panel.show();
-    this.image_panel = this.panel.get("image_panel_"+python_varname);
-    this.ticks = this.panel.get("ticks_"+python_varname);
-    var ticks = this.ticks;
-    var colorbar = this.panel.get("colorbar_"+python_varname);
-    this.metadata_panel = this.panel.get("rhs_panel_" + python_varname).get("metadata_" + python_varname);
-    this.zoom_scroll = this.panel.get("slider_" + python_varname);
-    var contour_window = this.panel.get("rhs_panel_" + python_varname);
-    contour_window = contour_window.get("editor_panel");
-    contour_window = contour_window.get("contour_edit");
-    var vector_window = this.panel.get("rhs_panel_" + python_varname);
-    vector_window = vector_window.get("editor_panel");
-    vector_window = vector_window.get("vector_edit");
-    var image_dom = this.image_panel.el.dom;
-    var control_panel = this.panel;
-    var metadata_string;
-
-    this.accept_results = function(payload) {
-        this.image_panel.el.dom.src = "data:image/png;base64," + payload['image_data'];
-        this.zoom_scroll.setValue(0, payload['zoom'], true);
-        this.metadata_panel.update(payload['metadata_string']);
-        metadata_string = payload['metadata_string'];
-        ticks.removeAll();
-        Ext.each(payload['ticks'], function(tick, index) {
-            ticks.add({xtype:'panel',
-                       width: 10, height:1,
-                       style: 'background-color: #000000;',
-                       html:' ',
-                       x:0, y: 10 + tick[0]});
-            ticks.add({xtype:'panel',
-                       width: 90, height:15,
-                       border: false,
-                       style: 'font-family: "Inconsolata", monospace;' +
-                              'font-size: 12px;',
-                       html: '' + tick[2] + '',
-                       x:12, y: 4 + tick[0]});
-        });
-        if (payload['colorbar_image'] != null) {
-            colorbar.el.dom.src = "data:image/png;base64," +
-                payload['colorbar_image'];
-        }
-        ticks.doLayout();
-    }
-
-    yt_rpc.ExtDirectREPL.execute(
-        {code:python_varname + '.zoom(1.0)', hide:true},
-        cell_finished);
-}
-
-widget_types['plot_window'] = WidgetPlotWindow;


diff -r 47094c9542e2ad48b54789108882ddcf8faf9285 -r 62ef095a290cc6041ee9cb44794535b8884b2e0f yt/gui/reason/html/js/widget_progressbar.js
--- a/yt/gui/reason/html/js/widget_progressbar.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/**********************************************************************
-The Plot Window Widget
-
-Author: Matthew Turk <matthewturk at gmail.com>
-Affiliation: Columbia University
-Homepage: http://yt-project.org/
-License:
-  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
-
-  This file is part of yt.
-
-  yt is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 3 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-***********************************************************************/
-
-
-
-var WidgetProgressBar = function(python_varname, widget_data) {
-    this.id = 'pbar_top';
-
-    Ext.MessageBox.show({
-        title: 'yt is working ...',
-        msg: widget_data.title,
-        progressText: 'Progress',
-        width: 300,
-        progress: true,
-        closable: false,
-    });
-
-    this.accept_results = function(payload) {
-        var i = payload['value'];
-        if (i == -1) {
-            Ext.MessageBox.hide();
-        } else {
-            Ext.MessageBox.updateProgress(i, Math.round(100*i)+'% completed');
-        }
-    }
-
-}
-
-widget_types['progressbar'] = WidgetProgressBar;


diff -r 47094c9542e2ad48b54789108882ddcf8faf9285 -r 62ef095a290cc6041ee9cb44794535b8884b2e0f yt/gui/reason/html/js/widget_streamlineviewer.js
--- a/yt/gui/reason/html/js/widget_streamlineviewer.js
+++ /dev/null
@@ -1,217 +0,0 @@
-/**********************************************************************
-The Streamline Viewer Widget
-
-Author: Samuel Skillman <samskillman at gmail.com>
-Affiliation: University of Colorado at Boulder
-Author: Matthew Turk <matthewturk at gmail.com>
-Affiliation: Columbia University
-Homepage: http://yt-project.org/
-License:
-  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
-
-  This file is part of yt.
-
-  yt is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 3 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-***********************************************************************/
-
-
-
-var WidgetStreamlineViewer = function(python_varname, widget_data) {
-    this.id = python_varname;
-    this.widget_data = widget_data;
-    examine = "canvas_" + python_varname;
-    var StreamlineViewerStart = function() {
-        this.curX = 0;
-        this.curY = 0;
-        this.dist = 0;
-        function updateBasedOnOffset(camera, offset){
-        camera.position.x = camera.target.x + offset.x;
-        camera.position.y = camera.target.y + offset.y;
-        camera.position.z = camera.target.z + offset.z;
-        }
-        function camGetOffset(camera){
-        return PhiloGL.Vec3.sub(camera.position, camera.target)
-            }
-        PhiloGL('canvas_' + python_varname, {
-            camera: {
-            position: {
-                x: 0.5, y: 0.5, z: 5
-                },
-                target: {
-                x: 0.5, y: 0.5, z: 0.5
-                },
-                },
-            program: {
-            from: 'ids',
-                vs: 'sl-shader-vs',
-                fs: 'sl-shader-fs'
-                },    
-            events: {
-            onDragStart: function(e) {
-                pos = {
-                x: e.x,
-                y: e.y
-                };
-                this.curX = e.x;
-                this.curY = e.y;
-                this.dist = camGetOffset(this.camera).norm();
-            },
-                onDragEnd: function(e) {
-                pos = {
-                x: e.x,
-                y: e.y
-                };
-            },
-                onDragMove: function(e) {
-                var c = this.camera;
-                var off = camGetOffset(c);
-                // Get Horizontal vector
-                var horiz = PhiloGL.Vec3.cross(c.up, 
-                               camGetOffset(c))
-                horiz.$scale(1./horiz.norm());
-
-                if (e.event.button == 0){ // Rotation
-                // Do vertical rotation about horizontal vector
-                var vert_rot = new PhiloGL.Mat4();
-                vert_rot.id();
-                vert_rot.$rotateAxis((e.y-this.curY)/100., horiz);
-                PhiloGL.Mat4.$mulVec3(vert_rot, off);
-                PhiloGL.Mat4.$mulVec3(vert_rot, c.up);
-                c.up.$scale(1./c.up.norm());
-
-                // Do horizontal rotation about up vector
-                var side_rot = new PhiloGL.Mat4();
-                side_rot.id();
-                side_rot.$rotateAxis(-(e.x-this.curX)/100., c.up);
-                side_rot.$mulVec3(off);
-        
-                // Update current positions
-                this.curX = e.x;
-                this.curY = e.y;
-                this.dist = off.norm();
-                updateBasedOnOffset(c, off);
-                c.update();
-                } else if (e.event.button = 2){ // Right click - transpose
-		    var tscale = 1.0*off.norm()/512.;
-		    var move_up = c.up.scale(-(e.y-this.curY)*tscale);
-		    var move_over = horiz.scale(-(e.x-this.curX)*tscale);
-                c.position.$add(move_up);
-                c.position.$add(move_over);
-                c.target.$add(move_up);
-                c.target.$add(move_over);
-                // Update current positions
-                this.curX = e.x;
-                this.curY = e.y;
-                c.update();
-                }
-    
-            },
-                onMouseWheel: function(e){
-                e.stop();
-                var offset = PhiloGL.Vec3.scale(camGetOffset(this.camera),
-                                1.0 - e.wheel/10.);
-                updateBasedOnOffset(this.camera, offset);
-                this.camera.update();
-            }
-            },
-            onError: function() {
-            alert("An error ocurred while loading the application");
-            },
-            onLoad: function(app) {
-            var gl = app.gl,
-                canvas = app.canvas,
-                program = app.program,
-                scene = app.scene,
-                camera = app.camera;
-
-	    gl.viewport(0, 0, canvas.width, canvas.height);
-	    gl.clearColor(0, 0, 0, 1);
-	    gl.clearDepth(1);
-	    gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
-	    gl.enable(gl.BLEND);
-	    gl.disable(gl.DEPTH_TEST);
-	    program.setUniform('alpha', 0.8);
-
-	    program.setBuffers({
-
-		    'shapeset': {
-			attribute: 'aVertexPosition',
-			    value: new Float32Array(widget_data['stream_positions']),
-			    size: 3
-			    },
-			
-			'shapesetColors': {
-			    attribute: 'aVertexColor',
-				value: new Float32Array(widget_data['stream_colors']),
-				size: 4
-			    },
-			    });
-
-
-	    camera.view.id();
-	    setInterval(draw, 30/60);
-	    var stream_counter =0;
-	    //Draw the scene
-	    function draw() {
-		stream_counter = 0;
-		gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
-		//Draw Triangle
-		program.setUniform('uMVMatrix', camera.view);
-		program.setUniform('uPMatrix', camera.projection);
-		program.setBuffer('shapeset');
-		program.setBuffer('shapesetColors');
-		for (var i=0; i<widget_data['n_streamlines']; i++){
-		    gl.drawArrays(gl.LINES, stream_counter, widget_data['stream_lengths'][i]-1);
-		    gl.drawArrays(gl.LINES, stream_counter+1, widget_data['stream_lengths'][i]-1);
-		    stream_counter += widget_data['stream_lengths'][i];
-		}
-		
-	    }
-	    }
-        });  
-    }        
-
-    viewport.get("center-panel").add(
-        {
-            xtype: 'panel',
-            id: "sl_" + python_varname,
-            title: "WebGL Streamline Viewer",
-            iconCls: 'graph',
-            autoScroll: true,
-            layout:'absolute',
-            closable: true,
-            items: [
-                { xtype:'panel',
-                  autoEl: {
-                    tag: 'canvas',
-                    id: 'canvas_' + python_varname,
-                    style: 'border: none;',
-                    width: 512, height:512
-                  },
-                  width: 512,
-                  height: 512
-                }],
-            listeners: { afterlayout: StreamlineViewerStart },
-        }
-    );
-
-    viewport.get("center-panel").activate("sl_" + this.id);
-    viewport.doLayout();
-    this.panel = viewport.get("center-panel").get("sl_" + python_varname);
-    this.panel.doLayout();
-
-    this.accept_results = function(payload) { }
-}
-
-widget_types['streamline_viewer'] = WidgetStreamlineViewer;



https://bitbucket.org/yt_analysis/yt/changeset/629538e3df60/
changeset:   629538e3df60
branch:      yt
user:        MatthewTurk
date:        2012-05-31 14:15:15
summary:      * Fix up MIME typing, but kind of hacky
 * Add an initial proof of concept of widget registration
 * Add the new WidgetDirector, which will handle payload delivery and widget
   creation.  Needs a store.
affected #:  6 files

diff -r 62ef095a290cc6041ee9cb44794535b8884b2e0f -r 629538e3df609aa2f646d34e8da754e2891ab43a yt/gui/reason/bottle_mods.py
--- a/yt/gui/reason/bottle_mods.py
+++ b/yt/gui/reason/bottle_mods.py
@@ -25,7 +25,7 @@
 """
 
 from yt.utilities.bottle import \
-    server_names, debug, route, run, request, ServerAdapter
+    server_names, debug, route, run, request, ServerAdapter, response
 import uuid
 from extdirect_router import DirectRouter, DirectProviderDefinition
 import json
@@ -121,6 +121,7 @@
     def _myapi(self):
         dpd = DirectProviderDefinition(self, self.api_url, ns="yt_rpc")
         source = "Ext.Direct.addProvider(%s);" % json.dumps(dpd._config())
+        response.headers['Content-Type'] = "text/javascript"
         return source
 
     def __call__(self):


diff -r 62ef095a290cc6041ee9cb44794535b8884b2e0f -r 629538e3df609aa2f646d34e8da754e2891ab43a yt/gui/reason/extdirect_repl.py
--- a/yt/gui/reason/extdirect_repl.py
+++ b/yt/gui/reason/extdirect_repl.py
@@ -50,7 +50,7 @@
 
 from .bottle_mods import preroute, BottleDirectRouter, notify_route, \
                          PayloadHandler
-from yt.utilities.bottle import response, request, route
+from yt.utilities.bottle import response, request, route, static_file
 from .basic_repl import ProgrammaticREPL
 
 try:
@@ -194,11 +194,6 @@
     matplotlib.rcParams["backend"] = "module://reason_agg"
     pylab.switch_backend("module://reason_agg")
 
-def static_file(fn):
-    def _static(self):
-        return open(os.path.join(local_dir, fn)).read()
-    return _static
-
 class ExtDirectREPL(ProgrammaticREPL, BottleDirectRouter):
     _skip_expose = ('index')
     my_name = "ExtDirectREPL"
@@ -263,7 +258,9 @@
         handler.setFormatter(formatter)
         ytLogger.addHandler(handler)
 
-    index = static_file("html/index.html")
+    def index(self):
+        root = os.path.join(local_dir, "html")
+        return static_file("index.html", root)
 
     def heartbeat(self):
         self.last_heartbeat = time.time()
@@ -307,7 +304,9 @@
         for t in threading.enumerate():
             print "Found a living thread:", t
 
-    _help_html = static_file("html/help.html")
+    def _help_html(self):
+        root = os.path.join(local_dir, "html")
+        return static_file("help.html", root)
 
     def _extjs(self, path):
         pp = os.path.join("extjs-4.1.0", path)
@@ -316,16 +315,20 @@
         except KeyError:
             response.status = 404
             return
+        if path[-4:].lower() in (".png", ".gif", ".jpg"):
+            response.headers['Content-Type'] = "image/%s" % (path[-3:].lower())
+        elif path[-4:].lower() == ".css":
+            response.headers['Content-Type'] = "text/css"
+        elif path[-3:].lower() == ".js":
+            response.headers['Content-Type'] = "text/javascript"
         return f.read()
 
     def _app(self, path):
-        pp = os.path.join(local_dir, "html", path)
-        if not os.path.exists(pp):
-            response.status = 404
-            return
-        return open(pp).read()
+        root = os.path.join(local_dir, "html")
+        return static_file(path, root)
 
     def _highlighter_css(self):
+        response.headers['Content-Type'] = "text/css"
         return highlighter_css
 
     def execute(self, code, hide = False):


diff -r 62ef095a290cc6041ee9cb44794535b8884b2e0f -r 629538e3df609aa2f646d34e8da754e2891ab43a yt/gui/reason/html/app.js
--- a/yt/gui/reason/html/app.js
+++ b/yt/gui/reason/html/app.js
@@ -36,7 +36,9 @@
 Ext.application({
     requires: ['Ext.container.Viewport',
                'Reason.view.LoggingGrid',
-               'Reason.view.DataObjectTree'],
+               'Reason.view.DataObjectTree',
+               'Reason.controller.widgets.SampleWidget',
+               ],
     name: 'Reason',
 
     appFolder: 'app',
@@ -93,5 +95,7 @@
         'DataObjects',
         'Notebook',
         'PayloadDirector',
+        'WidgetDirector',
     ],
+
 });


diff -r 62ef095a290cc6041ee9cb44794535b8884b2e0f -r 629538e3df609aa2f646d34e8da754e2891ab43a yt/gui/reason/html/app/controller/WidgetDirector.js
--- /dev/null
+++ b/yt/gui/reason/html/app/controller/WidgetDirector.js
@@ -0,0 +1,38 @@
+/**********************************************************************
+Widget controller class
+
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define('Reason.controller.WidgetDirector', {
+    extend: 'Ext.app.Controller',
+    requires: ["Reason.controller.widgets.SampleWidget"],
+
+    init: function() {
+        Ext.iterate(Reason.controller.widgets, function(i, w, ws) {
+            if (w.prototype.widgetName == null) {return;}
+            console.log("Registering " + w.prototype.widgetName);
+        });
+        this.callParent(arguments);
+    },
+
+});


diff -r 62ef095a290cc6041ee9cb44794535b8884b2e0f -r 629538e3df609aa2f646d34e8da754e2891ab43a yt/gui/reason/html/app/controller/widgets/BaseWidget.js
--- /dev/null
+++ b/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
@@ -0,0 +1,37 @@
+/**********************************************************************
+Base widget class
+
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define('Reason.controller.widgets.BaseWidget', {
+    extend: 'Ext.app.Controller',
+
+    statics: {
+        widgetTypes: [],
+        register: function(widgetName, widgetClass) {
+            alert(widgetName);
+            examine = widgetClass;
+        },
+    },
+
+});


diff -r 62ef095a290cc6041ee9cb44794535b8884b2e0f -r 629538e3df609aa2f646d34e8da754e2891ab43a yt/gui/reason/html/app/controller/widgets/SampleWidget.js
--- /dev/null
+++ b/yt/gui/reason/html/app/controller/widgets/SampleWidget.js
@@ -0,0 +1,30 @@
+/**********************************************************************
+Sample widget class
+
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define('Reason.controller.widgets.SampleWidget', {
+    extend: 'Reason.controller.widgets.BaseWidget',
+    widgetName: 'sample_widget',
+    statics: { something: 1, },
+});



https://bitbucket.org/yt_analysis/yt/changeset/2a1ed18b630a/
changeset:   2a1ed18b630a
branch:      yt
user:        MatthewTurk
date:        2012-05-31 17:13:55
summary:     The data object tree now works, with the addition of the model.  Widget
instances and classes now have stores.
affected #:  7 files

diff -r 629538e3df609aa2f646d34e8da754e2891ab43a -r 2a1ed18b630aaced5569ef16de137c2f58de4744 yt/gui/reason/html/app/controller/DataObjects.js
--- a/yt/gui/reason/html/app/controller/DataObjects.js
+++ b/yt/gui/reason/html/app/controller/DataObjects.js
@@ -32,6 +32,7 @@
 Ext.define('Reason.controller.DataObjects', {
     extend: 'Ext.app.Controller',
     stores: [ 'DataObjects' ],
+    models: ['DataObject'],
     view: ['DataObjectTree'],
     refs: [
         { ref: 'dataObjectTree',


diff -r 629538e3df609aa2f646d34e8da754e2891ab43a -r 2a1ed18b630aaced5569ef16de137c2f58de4744 yt/gui/reason/html/app/controller/WidgetDirector.js
--- a/yt/gui/reason/html/app/controller/WidgetDirector.js
+++ b/yt/gui/reason/html/app/controller/WidgetDirector.js
@@ -26,13 +26,24 @@
 Ext.define('Reason.controller.WidgetDirector', {
     extend: 'Ext.app.Controller',
     requires: ["Reason.controller.widgets.SampleWidget"],
+    stores: ['WidgetTypes', 'WidgetInstances'],
 
     init: function() {
+        var store = this.getWidgetTypesStore();
         Ext.iterate(Reason.controller.widgets, function(i, w, ws) {
             if (w.prototype.widgetName == null) {return;}
             console.log("Registering " + w.prototype.widgetName);
+            store.add({widgetname: w.prototype.widgetName,
+                       widgetclass: w});
+        });
+        this.application.addListener({
+            createwidget: {fn: this.createWidget, scope: this},
         });
         this.callParent(arguments);
     },
 
+    createWidget: function(widgetType, dataObject) {
+        console.log("Asked to create " + widgetType);
+    },
+
 });


diff -r 629538e3df609aa2f646d34e8da754e2891ab43a -r 2a1ed18b630aaced5569ef16de137c2f58de4744 yt/gui/reason/html/app/model/DataObject.js
--- /dev/null
+++ b/yt/gui/reason/html/app/model/DataObject.js
@@ -0,0 +1,29 @@
+/**********************************************************************
+Data object model
+
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define('Reason.model.DataObject', {
+    extent: 'Ext.data.Model',
+    fields: ['name', 'type', 'filename', 'field_list', 'varname'],
+});


diff -r 629538e3df609aa2f646d34e8da754e2891ab43a -r 2a1ed18b630aaced5569ef16de137c2f58de4744 yt/gui/reason/html/app/store/DataObjects.js
--- a/yt/gui/reason/html/app/store/DataObjects.js
+++ b/yt/gui/reason/html/app/store/DataObjects.js
@@ -31,7 +31,7 @@
 
 Ext.define('Reason.store.DataObjects', {
     extend: 'Ext.data.TreeStore',
-    fields: ['name', 'type', 'filename', 'field_list', 'varname'],
+    model: 'Reason.model.DataObject',
     data: [],
 });
 


diff -r 629538e3df609aa2f646d34e8da754e2891ab43a -r 2a1ed18b630aaced5569ef16de137c2f58de4744 yt/gui/reason/html/app/store/WidgetInstances.js
--- /dev/null
+++ b/yt/gui/reason/html/app/store/WidgetInstances.js
@@ -0,0 +1,37 @@
+/**********************************************************************
+Widget instance store for Reason
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define('Reason.store.WidgetInstances', {
+    extend: 'Ext.data.Store',
+    id: 'widgetinstances',
+    fields: ['widgetid', 'widgettype', 'widget'],
+    data: [],
+});


diff -r 629538e3df609aa2f646d34e8da754e2891ab43a -r 2a1ed18b630aaced5569ef16de137c2f58de4744 yt/gui/reason/html/app/store/WidgetTypes.js
--- /dev/null
+++ b/yt/gui/reason/html/app/store/WidgetTypes.js
@@ -0,0 +1,37 @@
+/**********************************************************************
+Widget class store for Reason
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define('Reason.store.WidgetTypes', {
+    extend: 'Ext.data.Store',
+    id: 'widgettypes',
+    fields: ['widgetname', 'widgetclass'],
+    data: [],
+});


diff -r 629538e3df609aa2f646d34e8da754e2891ab43a -r 2a1ed18b630aaced5569ef16de137c2f58de4744 yt/gui/reason/html/app/view/DataObjectTree.js
--- a/yt/gui/reason/html/app/view/DataObjectTree.js
+++ b/yt/gui/reason/html/app/view/DataObjectTree.js
@@ -47,6 +47,7 @@
         text: 'Name',
         sortable: false,
         dataIndex: 'text',
+        flex: 1.0,
     }],
 });
 



https://bitbucket.org/yt_analysis/yt/changeset/738ab7e2dd8d/
changeset:   738ab7e2dd8d
branch:      yt
user:        MatthewTurk
date:        2012-05-31 17:24:52
summary:     Merging from tip, to get the file load dialog stuff.
affected #:  13 files

diff -r 2a1ed18b630aaced5569ef16de137c2f58de4744 -r 738ab7e2dd8d85f9b02a4ad1cddab86a6dd03b53 MANIFEST.in
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,3 +1,3 @@
 include distribute_setup.py
-recursive-include yt/gui/reason/html/ *.html *.png *.ico *.js
-recursive-include yt/ *.pyx *.pxd *.hh *.h README* 
+recursive-include yt/gui/reason/html *.html *.png *.ico *.js
+recursive-include yt *.pyx *.pxd *.hh *.h README* 


diff -r 2a1ed18b630aaced5569ef16de137c2f58de4744 -r 738ab7e2dd8d85f9b02a4ad1cddab86a6dd03b53 doc/install_script.sh
--- a/doc/install_script.sh
+++ b/doc/install_script.sh
@@ -353,7 +353,7 @@
 
 # Now we dump all our SHA512 files out.
 
-echo '8da1b0af98203254a1cf776d73d09433f15b5090871f9fd6d712cea32bcd44446b7323ae1069b28907d2728e77944a642825c61bc3b54ceb46c91897cc4f6051  Cython-0.15.1.tar.gz' > Cython-0.15.1.tar.gz.sha512
+echo '2c1933ab31246b4f4eba049d3288156e0a72f1730604e3ed7357849967cdd329e4647cf236c9442ecfb06d0aff03e6fc892a7ba2a5c1cf5c011b7ab9c619acec  Cython-0.16.tar.gz ' > Cython-0.16.tar.gz.sha512
 echo 'b8a12bf05b3aafa71135e47da81440fd0f16a4bd91954bc5615ad3d3b7f9df7d5a7d5620dc61088dc6b04952c5c66ebda947a4cfa33ed1be614c8ca8c0f11dff  PhiloGL-1.4.2.zip' > PhiloGL-1.4.2.zip.sha512
 echo '44eea803870a66ff0bab08d13a8b3388b5578ebc1c807d1d9dca0a93e6371e91b15d02917a00b3b20dc67abb5a21dabaf9b6e9257a561f85eeff2147ac73b478  PyX-0.11.1.tar.gz' > PyX-0.11.1.tar.gz.sha512
 echo '1a754d560bfa433f0960ab3b5a62edb5f291be98ec48cf4e5941fa5b84139e200b87a52efbbd6fa4a76d6feeff12439eed3e7a84db4421940d1bbb576f7a684e  Python-2.7.2.tgz' > Python-2.7.2.tgz.sha512
@@ -391,7 +391,7 @@
 get_enzotools mercurial-2.2.tar.gz
 get_enzotools ipython-0.12.tar.gz
 get_enzotools h5py-2.0.1.tar.gz
-get_enzotools Cython-0.15.1.tar.gz
+get_enzotools Cython-0.16.tar.gz
 get_enzotools ext-3.3.2.zip
 get_enzotools ext-slate-110328.zip
 get_enzotools PhiloGL-1.4.2.zip
@@ -631,7 +631,7 @@
 
 do_setup_py ipython-0.12
 do_setup_py h5py-2.0.1
-do_setup_py Cython-0.15.1
+do_setup_py Cython-0.16
 [ $INST_PYX -eq 1 ] && do_setup_py PyX-0.11.1
 
 echo "Doing yt update, wiping local changes and updating to branch ${BRANCH}"


diff -r 2a1ed18b630aaced5569ef16de137c2f58de4744 -r 738ab7e2dd8d85f9b02a4ad1cddab86a6dd03b53 scripts/iyt
--- a/scripts/iyt
+++ b/scripts/iyt
@@ -1,5 +1,6 @@
 #!python
 import os, re
+from distutils import version
 from yt.mods import *
 from yt.data_objects.data_containers import AMRData
 namespace = locals().copy()
@@ -22,6 +23,11 @@
     code.interact(doc, None, namespace)
     sys.exit()
 
+if version.LooseVersion(IPython.__version__) <= version.LooseVersion('0.10'):
+    api_version = '0.10'
+else:
+    api_version = '0.11'
+
 if IPython.__version__.startswith("0.10"):
     api_version = '0.10'
 elif IPython.__version__.startswith("0.11") or \


diff -r 2a1ed18b630aaced5569ef16de137c2f58de4744 -r 738ab7e2dd8d85f9b02a4ad1cddab86a6dd03b53 yt/data_objects/data_containers.py
--- a/yt/data_objects/data_containers.py
+++ b/yt/data_objects/data_containers.py
@@ -3367,9 +3367,18 @@
             The resolution level data is uniformly gridded at
         left_edge : array_like
             The left edge of the region to be extracted
-        right_edge : array_like
+        dims : array_like
+            Number of cells along each axis of resulting covering_grid
+        right_edge : array_like, optional
             The right edge of the region to be extracted
-
+        fields : array_like, optional
+            A list of fields that you'd like pre-generated for your object
+
+        Example
+        -------
+        cube = pf.h.covering_grid(2, left_edge=[0.0, 0.0, 0.0], \
+                                  right_edge=[1.0, 1.0, 1.0],
+                                  dims=[128, 128, 128])
         """
         AMR3DData.__init__(self, center=kwargs.pop("center", None),
                            fields=fields, pf=pf, **kwargs)
@@ -3505,7 +3514,8 @@
     @wraps(AMRCoveringGridBase.__init__)
     def __init__(self, *args, **kwargs):
         """A 3D region with all data extracted and interpolated to a
-        single, specified resolution.
+        single, specified resolution. (Identical to covering_grid,
+        except that it interpolates.)
 
         Smoothed covering grids start at level 0, interpolating to
         fill the region to level 1, replacing any cells actually
@@ -3518,9 +3528,18 @@
             The resolution level data is uniformly gridded at
         left_edge : array_like
             The left edge of the region to be extracted
-        right_edge : array_like
+        dims : array_like
+            Number of cells along each axis of resulting covering_grid
+        right_edge : array_like, optional
             The right edge of the region to be extracted
-
+        fields : array_like, optional
+            A list of fields that you'd like pre-generated for your object
+
+        Example
+        -------
+        cube = pf.h.smoothed_covering_grid(2, left_edge=[0.0, 0.0, 0.0], \
+                                  right_edge=[1.0, 1.0, 1.0],
+                                  dims=[128, 128, 128])
         """
         self._base_dx = (
               (self.pf.domain_right_edge - self.pf.domain_left_edge) /


diff -r 2a1ed18b630aaced5569ef16de137c2f58de4744 -r 738ab7e2dd8d85f9b02a4ad1cddab86a6dd03b53 yt/gui/reason/extdirect_repl.py
--- a/yt/gui/reason/extdirect_repl.py
+++ b/yt/gui/reason/extdirect_repl.py
@@ -26,6 +26,7 @@
 
 import json
 import os
+import stat
 import cStringIO
 import logging
 import uuid
@@ -434,6 +435,36 @@
         return command
 
     @lockit
+    def load(self, base_dir, filename):
+        pp = os.path.join(base_dir, filename)
+        funccall = "pfs.append(load('%s'))" % pp
+        self.execute(funccall)
+        return []
+
+    def file_listing(self, base_dir, sub_dir):
+        if base_dir == "":
+            cur_dir = os.getcwd()
+        elif sub_dir == "":
+            cur_dir = base_dir
+        else:
+            cur_dir = os.path.join(base_dir, sub_dir)
+            cur_dir = os.path.abspath(cur_dir)
+        if not os.path.isdir(cur_dir):
+            return {'change':False}
+        fns = os.listdir(cur_dir)
+        results = [("..", 0, "directory")]
+        for fn in sorted((os.path.join(cur_dir, f) for f in fns)):
+            if not os.access(fn, os.R_OK): continue
+            if os.path.isfile(fn):
+                size = os.path.getsize(fn)
+                t = "file"
+            else:
+                size = 0
+                t = "directory"
+            results.append((os.path.basename(fn), size, t))
+        return dict(objs = results, cur_dir=cur_dir)
+
+    @lockit
     def create_phase(self, objname, field_x, field_y, field_z, weight):
         if weight == "None": weight = None
         else: weight = "'%s'" % (weight)




diff -r 2a1ed18b630aaced5569ef16de137c2f58de4744 -r 738ab7e2dd8d85f9b02a4ad1cddab86a6dd03b53 yt/gui/reason/html/js/file_open.js
--- /dev/null
+++ b/yt/gui/reason/html/js/file_open.js
@@ -0,0 +1,146 @@
+/**********************************************************************
+A file opener
+
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2012 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+function open_file() {
+    var filestore = new Ext.data.ArrayStore({
+      fields: ['filename', 
+               {name:'size', type:'float'},
+               'type'
+      ]
+    });
+    var cur_dir;
+    function fillStore(f, a){
+        if(a.status == false){
+          Ext.Msg.alert("Error", "Something has gone wrong.");
+          return;
+        }
+        if(a.result['change'] == false) {
+          win.get("current_file").setValue(cur_dir);
+          return;
+        }
+        filestore.removeAll();
+        var rec = [];
+        filestore.loadData(a.result['objs']);
+        cur_dir = a.result['cur_dir'];
+        win.get("current_file").setValue(cur_dir);
+    }
+
+    var win = new Ext.Window({
+        layout:'vbox',
+        layoutConfig: {
+            align: 'stretch',
+            pack: 'start',
+            defaultMargins: "5px 5px 5px 5px",
+        },
+        width:540,
+        height:480,
+        modal:true,
+        resizable:true,
+        draggable:true,
+        title:'Open File',
+        items: [
+            { xtype: 'textfield',
+              id: 'current_file',
+              listeners: {
+                specialkey: function(f, e) {
+                  if (e.getKey() != e.ENTER) { return; }
+                  yt_rpc.ExtDirectREPL.file_listing(
+                        {base_dir:f.getValue(), sub_dir:''}, fillStore);
+                }
+              }
+            }, {
+              xtype:'listview',
+              id: 'file_listing',
+              store: filestore ,
+              singleSelect:true,
+              emptyText: 'No images to display',
+              flex: 1.0,
+              columns: [
+              {
+                  header: 'Type',
+                  width: 0.1,
+                  tpl: '<img src="images/file_dialog_{type}.png" width=16 height=16>',
+                  dataIndex: 'type'
+              },{
+                  header: 'Filename',
+                  width: .75,
+                  dataIndex: 'filename'
+              },{
+                  header: 'Size',
+                  dataIndex: 'size',
+                  tpl: '{size:fileSize}',
+                  align: 'right',
+                  cls: 'listview-filesize'
+              }],
+              listeners: {
+                dblclick: function(view, index, node, e) {
+                    var fileRecord = filestore.getAt(index).data;
+                    if (fileRecord.type == 'directory') {
+                      yt_rpc.ExtDirectREPL.file_listing(
+                            {base_dir:cur_dir, sub_dir:fileRecord.filename},
+                            fillStore);
+                    } else {
+                      yt_rpc.ExtDirectREPL.load(
+                            {base_dir:cur_dir, filename:fileRecord.filename},
+                            handle_result);
+                      win.destroy();
+                    }
+                },
+                selectionchange: function(view, index, node, e) {
+                },
+              },
+            }, {
+              xtype: 'panel',
+              height: 40,
+              layout: 'hbox',
+              layoutConfig: {
+                  align: 'stretch',
+                  pack: 'start',
+                  defaultMargins: "5px 5px 5px 5px",
+              },
+              items: [
+                { flex: 1.0, xtype: 'button', text: 'Cancel',
+                    handler: function(b, e) { win.destroy(); } },
+                { flex: 1.0, xtype: 'button', text: 'Load',
+                    handler: function(b, e) {
+                      filename = "";
+                      var fl = win.get("file_listing");
+                      if (fl.getSelectionCount() == 1) {
+                        filename = fl.getSelectedRecords()[0].data.filename;
+                      }
+                      yt_rpc.ExtDirectREPL.load(
+                            {base_dir:cur_dir, filename:filename},
+                            handle_result);
+                      win.destroy();
+                    }
+                },
+              ],
+            },
+        ],
+    });
+    yt_rpc.ExtDirectREPL.file_listing(
+          {base_dir:"", sub_dir:""}, fillStore);
+    win.show(this);
+}


diff -r 2a1ed18b630aaced5569ef16de137c2f58de4744 -r 738ab7e2dd8d85f9b02a4ad1cddab86a6dd03b53 yt/gui/reason/html/js/menu_items.js
--- a/yt/gui/reason/html/js/menu_items.js
+++ b/yt/gui/reason/html/js/menu_items.js
@@ -33,7 +33,11 @@
     text: 'Menu',
     id: 'main_menu',
     menu: [
-           {xtype:'menuitem', text: 'Open', disabled: true},
+           {xtype:'menuitem', text: 'Open File', 
+               handler: function(b,e) {
+                  open_file()
+               },
+           },
            {xtype:'menuitem', text: 'Open Directory', disabled: true},
            {xtype: 'menuseparator'},
            {xtype:'menuitem', text: 'Save Script',


diff -r 2a1ed18b630aaced5569ef16de137c2f58de4744 -r 738ab7e2dd8d85f9b02a4ad1cddab86a6dd03b53 yt/gui/reason/html/resources/images/file_dialog_directory.png
Binary file yt/gui/reason/html/resources/images/file_dialog_directory.png has changed


diff -r 2a1ed18b630aaced5569ef16de137c2f58de4744 -r 738ab7e2dd8d85f9b02a4ad1cddab86a6dd03b53 yt/gui/reason/html/resources/images/file_dialog_file.png
Binary file yt/gui/reason/html/resources/images/file_dialog_file.png has changed


diff -r 2a1ed18b630aaced5569ef16de137c2f58de4744 -r 738ab7e2dd8d85f9b02a4ad1cddab86a6dd03b53 yt/utilities/_amr_utils/misc_utilities.pyx
--- a/yt/utilities/_amr_utils/misc_utilities.pyx
+++ b/yt/utilities/_amr_utils/misc_utilities.pyx
@@ -287,6 +287,7 @@
         uniquedims[i] = <np.float64_t *> \
                 alloca(2*n_grids * sizeof(np.float64_t))
     my_max = 0
+    best_dim = -1
     for dim in range(3):
         n_unique = 0
         uniques = uniquedims[dim]


diff -r 2a1ed18b630aaced5569ef16de137c2f58de4744 -r 738ab7e2dd8d85f9b02a4ad1cddab86a6dd03b53 yt/utilities/amr_kdtree/amr_kdtree.py
--- a/yt/utilities/amr_kdtree/amr_kdtree.py
+++ b/yt/utilities/amr_kdtree/amr_kdtree.py
@@ -1012,7 +1012,7 @@
                     # This node belongs to someone else, move along
                     current_node, previous_node = self.step_depth(current_node, previous_node)
                     continue
-                
+
             # If we are down to one grid, we are either in it or the parent grid
             if len(current_node.grids) == 1:
                 thisgrid = current_node.grids[0]
@@ -1031,25 +1031,27 @@
                         if len(children) > 0:
                             current_node.grids = self.pf.hierarchy.grids[na.array(children,copy=False)]
                             current_node.parent_grid = thisgrid
-                            # print 'My single grid covers the rest of the volume, and I have children, about to iterate on them'
+                            #print 'My single grid covers the rest of the volume, and I have children, about to iterate on them'
                             del children
                             continue
 
                     # Else make a leaf node (brick container)
+                    #print 'My single grid covers the rest of the volume, and I have no children', thisgrid
                     set_leaf(current_node, thisgrid, current_node.l_corner, current_node.r_corner)
-                    # print 'My single grid covers the rest of the volume, and I have no children'
                     current_node, previous_node = self.step_depth(current_node, previous_node)
                     continue
 
             # If we don't have any grids, this volume belongs to the parent        
             if len(current_node.grids) == 0:
+                #print 'This volume does not have a child grid, so it belongs to my parent!'
                 set_leaf(current_node, current_node.parent_grid, current_node.l_corner, current_node.r_corner)
-                # print 'This volume does not have a child grid, so it belongs to my parent!'
                 current_node, previous_node = self.step_depth(current_node, previous_node)
                 continue
 
             # If we've made it this far, time to build a dividing node
-            self._build_dividing_node(current_node)
+            # print 'Building dividing node'
+            # Continue if building failed
+            if self._build_dividing_node(current_node): continue
 
             # Step to the nest node in a depth-first traversal.
             current_node, previous_node = self.step_depth(current_node, previous_node)
@@ -1058,10 +1060,10 @@
         '''
         Given a node, finds all the choices for the next dividing plane.  
         '''
-        data = na.array([(child.LeftEdge, child.RightEdge) for child in current_node.grids],copy=False)
         # For some reason doing dim 0 separately is slightly faster.
         # This could be rewritten to all be in the loop below.
 
+        data = na.array([(child.LeftEdge, child.RightEdge) for child in current_node.grids],copy=False)
         best_dim, split, less_ids, greater_ids = \
             kdtree_get_choices(data, current_node.l_corner, current_node.r_corner)
         return data[:,:,best_dim], best_dim, split, less_ids, greater_ids
@@ -1071,8 +1073,19 @@
         Makes the current node a dividing node, and initializes the
         left and right children.
         '''
-        
-        data,best_dim,split,less_ids,greater_ids = self._get_choices(current_node)
+
+        data = na.array([(child.LeftEdge, child.RightEdge) for child in current_node.grids],copy=False)
+        best_dim, split, less_ids, greater_ids = \
+            kdtree_get_choices(data, current_node.l_corner, current_node.r_corner)
+
+        del data
+
+        # Here we break out if no unique grids were found. In this case, there
+        # are likely overlapping grids, and we assume that the first grid takes
+        # precedence.  This is fragile.
+        if best_dim == -1:
+            current_node.grids = [current_node.grids[0]]
+            return 1
 
         current_node.split_ax = best_dim
         current_node.split_pos = split
@@ -1080,7 +1093,7 @@
         #greater_ids0 = (split < data[:,1])
         #assert(na.all(less_ids0 == less_ids))
         #assert(na.all(greater_ids0 == greater_ids))
-        
+
         current_node.left_child = MasterNode(my_id=_lchild_id(current_node.id),
                                              parent=current_node,
                                              parent_grid=current_node.parent_grid,
@@ -1099,7 +1112,9 @@
         # build to work.  The other deletions are just to save memory.
         del current_node.grids, current_node.parent_grid, current_node.brick,\
             current_node.li, current_node.ri, current_node.dims
-        
+
+        return 0
+
     def traverse(self, back_center, front_center, image):
         r"""Traverses the kd-Tree, casting the partitioned grids from back to
             front.


diff -r 2a1ed18b630aaced5569ef16de137c2f58de4744 -r 738ab7e2dd8d85f9b02a4ad1cddab86a6dd03b53 yt/utilities/command_line.py
--- a/yt/utilities/command_line.py
+++ b/yt/utilities/command_line.py
@@ -82,11 +82,15 @@
         if cls.npfs > 1:
             self(args)
         else:
-            if len(getattr(args, "pf", [])) > 1:
+            pf_args = getattr(args, "pf", [])
+            if len(pf_args) > 1:
                 pfs = args.pf
                 for pf in pfs:
                     args.pf = pf
                     self(args)
+            elif len(pf_args) == 0:
+                pfs = []
+                self(args)
             else:
                 args.pf = getattr(args, 'pf', [None])[0]
                 self(args)
@@ -105,6 +109,8 @@
 _common_options = dict(
     pf      = dict(short="pf", action=GetParameterFiles,
                    nargs="+", help="Parameter files to run on"),
+    opf     = dict(action=GetParameterFiles, dest="pf",
+                   nargs="*", help="(Optional) Parameter files to run on"),
     axis    = dict(short="-a", long="--axis",
                    action="store", type=int,
                    dest="axis", default=4,
@@ -1269,7 +1275,8 @@
                  help="At startup, find all *.hierarchy files in the CWD"),
             dict(short="-d", long="--debug", action="store_true",
                  default = False, dest="debug",
-                 help="Add a debugging mode for cell execution")
+                 help="Add a debugging mode for cell execution"),
+            "opf"
             )
     description = \
         """
@@ -1315,12 +1322,12 @@
         from yt.gui.reason.bottle_mods import uuid_serve_functions, PayloadHandler
         hr = ExtDirectREPL(base_extjs_path)
         hr.debug = PayloadHandler.debug = args.debug
+        command_line = ["pfs = []"]
         if args.find:
             # We just have to find them and store references to them.
-            command_line = ["pfs = []"]
             for fn in sorted(glob.glob("*/*.hierarchy")):
                 command_line.append("pfs.append(load('%s'))" % fn[:-10])
-            hr.execute("\n".join(command_line))
+        hr.execute("\n".join(command_line))
         bottle.debug()
         uuid_serve_functions(open_browser=args.open_browser,
                     port=int(args.port), repl=hr)
@@ -1430,7 +1437,7 @@
         if 'upload' in rv and 'links' in rv['upload']:
             print
             print "Image successfully uploaded!  You can find it at:"
-            print "    %s" % (rv['upload']['links']['imgur_page'])
+            print "    %s" % (rv['upload']['links']['original'])
             print
             print "If you'd like to delete it, visit this page:"
             print "    %s" % (rv['upload']['links']['delete_page'])



https://bitbucket.org/yt_analysis/yt/changeset/c45c2fbe66a8/
changeset:   c45c2fbe66a8
branch:      yt
user:        MatthewTurk
date:        2012-05-31 17:54:14
summary:     Importing old menu actions and display main menu.
affected #:  5 files

diff -r 738ab7e2dd8d85f9b02a4ad1cddab86a6dd03b53 -r c45c2fbe66a8986c28f4a2814c03640f41841761 yt/gui/reason/html/app.js
--- a/yt/gui/reason/html/app.js
+++ b/yt/gui/reason/html/app.js
@@ -38,6 +38,7 @@
                'Reason.view.LoggingGrid',
                'Reason.view.DataObjectTree',
                'Reason.controller.widgets.SampleWidget',
+               'Reason.view.MainMenu',
                ],
     name: 'Reason',
 
@@ -61,10 +62,8 @@
                     title: 'Status',
                     margins: '0 0 0 0',
                }, {
-                    xtype: 'dataobjecttree',
                     id: 'west-panel',
                     region: 'west',
-                    title: 'Data Objects',
                     split: true,
                     width: 200,
                     minSize: 175,
@@ -73,6 +72,10 @@
                     layout: {
                         type: 'anchor',
                     },
+                    items: [
+                        { xtype: 'mainmenu' },
+                        { xtype: 'dataobjecttree', },
+                    ],
               }, {
                 xtype: 'tabpanel',
                 region: 'center',
@@ -96,6 +99,7 @@
         'Notebook',
         'PayloadDirector',
         'WidgetDirector',
+        'MenuActions',
     ],
 
 });


diff -r 738ab7e2dd8d85f9b02a4ad1cddab86a6dd03b53 -r c45c2fbe66a8986c28f4a2814c03640f41841761 yt/gui/reason/html/app/controller/MenuActions.js
--- /dev/null
+++ b/yt/gui/reason/html/app/controller/MenuActions.js
@@ -0,0 +1,107 @@
+/**********************************************************************
+Menu actions in Reason
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+
+Ext.define('Reason.controller.MenuActions', {
+    extend: 'Ext.app.Controller',
+    view: ['MainMenu'],
+
+    init: function() {
+        this.callParent(arguments);
+    },
+
+    addLogEntry: function(payload) {
+        examine = payload;
+        this.getLogEntriesStore().add(
+            {record: payload['log_entry']}
+        );
+    },
+
+    saveScript: function (b,e) { 
+        Ext.Msg.prompt("We have important work to do.", 
+        "Enter filename.", 
+        function(btn, text) {
+            if (btn == 'ok'){
+                yt_rpc.ExtDirectREPL.save_session({filename:text}, 
+                function(f, a) {
+                    if (a.result['status'] == 'SUCCESS') {
+                        var alert_text = 'Saved session to ' + 
+                        a.result['filename']
+                        Ext.Msg.alert('Success!', alert_text);
+                        var record = new logging_store.recordType(
+                            {record: alert_text });
+                        logging_store.add(record, number_log_records++);
+                    } else {
+                        Ext.Msg.alert('Always naysaying!',
+                            'Failed to save to ' + 
+                            a.result['filename'] + 
+                            '<br>Error: ' + 
+                            a.result['error']);
+                    }
+                });
+            }
+        });
+    },
+
+    downloadScript: function(b, e) {
+        window.open("session.py", "_top"); 
+        var record = new logging_store.recordType({
+            record: 'Saved session locally.'});
+        logging_store.add(record, number_log_records++);
+    },
+
+    pastebinScript: function(b, e) {
+        yt_rpc.ExtDirectREPL.paste_session({}, function(f, a) {
+            if (a.result['status'] == 'SUCCESS') {
+                var alert_text = 'Pasted session to:<br>' + 
+                a.result['site']
+                var alert_text_rec = 'Pasted session to: ' + 
+                a.result['site']
+                Ext.Msg.alert('Pastebin', alert_text);
+                var record = new logging_store.recordType(
+                    {record: alert_text_rec });
+                logging_store.add(record, number_log_records++);
+            }
+        }); 
+    },
+
+    openIRCChannel: function(b, e) {
+        window.open("http://yt-project.org/irc.html", "_new");
+    },
+
+    quitReason: function(b, e) {
+        task_runner.stop(heartbeat)
+        yt_rpc.ExtDirectREPL.shutdown({}, function(f,a) { 
+        Ext.Msg.alert("Goodbye!", "Goodbye from Reason!", function() {
+        window.open("http://www.google.com/", "_top");});});
+    },
+});
+


diff -r 738ab7e2dd8d85f9b02a4ad1cddab86a6dd03b53 -r c45c2fbe66a8986c28f4a2814c03640f41841761 yt/gui/reason/html/app/view/DataObjectTree.js
--- a/yt/gui/reason/html/app/view/DataObjectTree.js
+++ b/yt/gui/reason/html/app/view/DataObjectTree.js
@@ -32,11 +32,11 @@
 Ext.define('Reason.view.DataObjectTree', {
     extend: 'Ext.tree.Panel',
     alias: 'widget.dataobjecttree',
-    title: 'Data Objects',
     store: 'DataObjects',
     itemId: 'dataobjects',
     rootVisible: false,
     iconCls: 'nav',
+    header: false,
     root: {
         expanded: true,
         text: '',
@@ -44,7 +44,7 @@
     },
     columns: [{
         xtype: 'treecolumn',
-        text: 'Name',
+        text: 'Object',
         sortable: false,
         dataIndex: 'text',
         flex: 1.0,


diff -r 738ab7e2dd8d85f9b02a4ad1cddab86a6dd03b53 -r c45c2fbe66a8986c28f4a2814c03640f41841761 yt/gui/reason/html/app/view/MainMenu.js
--- /dev/null
+++ b/yt/gui/reason/html/app/view/MainMenu.js
@@ -0,0 +1,53 @@
+/**********************************************************************
+Main Menu in Reason
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define('Reason.view.MainMenu', {
+    extend: 'Ext.toolbar.Toolbar',
+    alias: 'widget.mainmenu',
+    items: [
+      {
+        text: 'Reason Menu',
+        menu: [
+               {xtype: 'menuitem', text: 'Open File'},
+               {xtype: 'menuitem', text: 'Open Directory', disabled: true},
+               {xtype: 'menuseparator'},
+               {xtype: 'menuitem', text: 'Save Script'},
+               {xtype: 'menuitem', text: 'Download Script'},
+               {xtype: 'menuitem', text: 'Pastebin Script'},
+               {xtype: 'menuseparator'},
+               {xtype:'menuitem', text: 'yt Chat'},
+               {xtype: 'menuseparator'},
+               {xtype:'menuitem', text: 'Quit'},
+            ],
+      },
+    ],
+});
+


diff -r 738ab7e2dd8d85f9b02a4ad1cddab86a6dd03b53 -r c45c2fbe66a8986c28f4a2814c03640f41841761 yt/gui/reason/html/js/menu_items.js
--- a/yt/gui/reason/html/js/menu_items.js
+++ /dev/null
@@ -1,112 +0,0 @@
-/**********************************************************************
-The main GUI facility for Reason
-
-Author: Cameron Hummels <chummels at gmail.com>
-Affiliation: Columbia
-Author: Jeffrey S. Oishi <jsoishi at gmail.com>
-Affiliation: KIPAC/SLAC/Stanford
-Author: Britton Smith <brittonsmith at gmail.com>
-Affiliation: MSU
-Author: Matthew Turk <matthewturk at gmail.com>
-Affiliation: Columbia University
-Homepage: http://yt-project.org/
-License:
-  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
-
-  This file is part of yt.
-
-  yt is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 3 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-***********************************************************************/
-
-var main_menu = {
-    text: 'Menu',
-    id: 'main_menu',
-    menu: [
-           {xtype:'menuitem', text: 'Open File', 
-               handler: function(b,e) {
-                  open_file()
-               },
-           },
-           {xtype:'menuitem', text: 'Open Directory', disabled: true},
-           {xtype: 'menuseparator'},
-           {xtype:'menuitem', text: 'Save Script',
-	            handler: function (b,e) { 
-                    Ext.Msg.prompt("We have important work to do.", 
-                    "Enter filename.", 
-                    function(btn, text) {
-                        if (btn == 'ok'){
-                            yt_rpc.ExtDirectREPL.save_session({filename:text}, 
-                            function(f, a) {
-                                if (a.result['status'] == 'SUCCESS') {
-                                    var alert_text = 'Saved session to ' + 
-                                    a.result['filename']
-                                    Ext.Msg.alert('Success!', alert_text);
-                                    var record = new logging_store.recordType(
-                                        {record: alert_text });
-                                    logging_store.add(record, number_log_records++);
-							    } else {
-							        Ext.Msg.alert('Always naysaying!',
-                                        'Failed to save to ' + 
-                                        a.result['filename'] + 
-                                        '<br>Error: ' + 
-                                        a.result['error']);
-                                }
-                            });
-                        }
-                    });
-                } },
-           {xtype:'menuitem', text: 'Download Script',
-                handler: function(b, e) { 
-                    window.open("session.py", "_top"); 
-                    var record = new logging_store.recordType({
-                        record: 'Saved session locally.'});
-                    logging_store.add(record, number_log_records++);
-                    }},
-           {xtype:'menuitem', text: 'Pastebin Script',
-                handler: function (b,e) { 
-                    yt_rpc.ExtDirectREPL.paste_session({}, function(f, a) {
-                        if (a.result['status'] == 'SUCCESS') {
-                            var alert_text = 'Pasted session to:<br>' + 
-                            a.result['site']
-                            var alert_text_rec = 'Pasted session to: ' + 
-                            a.result['site']
-                            Ext.Msg.alert('Pastebin', alert_text);
-                            var record = new logging_store.recordType(
-                                {record: alert_text_rec });
-                            logging_store.add(record, number_log_records++);
-                        }
-                    }); 
-                }},
-           {xtype: 'menuseparator'},
-           {xtype:'menuitem', text: 'Help',
-                handler: function (b,e) { 
-                        window.open("help.html", "_new");
-            }},
-           {xtype:'menuitem', text: 'yt Chat',
-                handler: function (b,e) { 
-                        window.open("http://yt-project.org/irc.html", "_new");
-            }},
-           {xtype: 'menuseparator'},
-           {xtype:'menuitem', text: 'Quit',
-             handler: function(b,e) {
-                task_runner.stop(heartbeat)
-                yt_rpc.ExtDirectREPL.shutdown({}, function(f,a) { 
-                Ext.Msg.alert("Goodbye!", "Goodbye from Reason!", function() {
-                window.open("http://www.google.com/", "_top");});});
-                }
-           },
-                
-        ],
-};
-



https://bitbucket.org/yt_analysis/yt/changeset/943efa19ce9b/
changeset:   943efa19ce9b
branch:      yt
user:        MatthewTurk
date:        2012-05-31 18:28:30
summary:     Most menu items now work as before.  File open doesn't yet.
affected #:  5 files

diff -r c45c2fbe66a8986c28f4a2814c03640f41841761 -r 943efa19ce9ba190c5d14f345a6e029925fd00e7 yt/gui/reason/html/app.js
--- a/yt/gui/reason/html/app.js
+++ b/yt/gui/reason/html/app.js
@@ -38,7 +38,6 @@
                'Reason.view.LoggingGrid',
                'Reason.view.DataObjectTree',
                'Reason.controller.widgets.SampleWidget',
-               'Reason.view.MainMenu',
                ],
     name: 'Reason',
 


diff -r c45c2fbe66a8986c28f4a2814c03640f41841761 -r 943efa19ce9ba190c5d14f345a6e029925fd00e7 yt/gui/reason/html/app/controller/Logging.js
--- a/yt/gui/reason/html/app/controller/Logging.js
+++ b/yt/gui/reason/html/app/controller/Logging.js
@@ -36,14 +36,16 @@
 
     init: function() {
         this.application.addListener({
-            payloadlogentry: {fn: this.addLogEntry, scope: this},
+            payloadlogentry: {fn: this.addLogPayload, scope: this},
+            logentry: {fn: this.addLogEntry, scope: this},
         });
     },
 
-    addLogEntry: function(payload) {
-        examine = payload;
-        this.getLogEntriesStore().add(
-            {record: payload['log_entry']}
-        );
+    addLogPayload: function(payload) {
+        this.addLogEntry(payload['log_entry']);
+    },
+
+    addLogEntry: function(text) {
+        this.getLogEntriesStore().add({record: text});
     },
 });


diff -r c45c2fbe66a8986c28f4a2814c03640f41841761 -r 943efa19ce9ba190c5d14f345a6e029925fd00e7 yt/gui/reason/html/app/controller/MenuActions.js
--- a/yt/gui/reason/html/app/controller/MenuActions.js
+++ b/yt/gui/reason/html/app/controller/MenuActions.js
@@ -32,50 +32,52 @@
 
 Ext.define('Reason.controller.MenuActions', {
     extend: 'Ext.app.Controller',
-    view: ['MainMenu'],
+    views: ['MainMenu'],
 
     init: function() {
+        this.control({
+            '#openfile': { click: this.openFile },
+            '#savescript': { click: this.saveScript},
+            '#downloadscript': { click: this.downloadScript },
+            '#pastebinscript': { click: this.pastebinScript },
+            '#ytchat': {click: this.openIRCChannel },
+            '#quit': {click: this.quitReason },
+        });
         this.callParent(arguments);
     },
 
-    addLogEntry: function(payload) {
-        examine = payload;
-        this.getLogEntriesStore().add(
-            {record: payload['log_entry']}
+    saveScript: function (b,e) { 
+        /* This function gets called on success */
+        var controller = this;
+        function handleResponse(f, a) {
+            if (a.result['status'] == 'SUCCESS') {
+                var alert_text = 'Saved session to ' + a.result['filename'];
+                Ext.Msg.alert('Success!', alert_text);
+                controller.application.fireEvent("logentry", alert_text);
+            } else {
+                Ext.Msg.alert('Always naysaying!',
+                  'Failed to save to ' + a.result['filename'] + '<br>Error: ' +
+                  a.result['error']);
+           }
+        };
+        /* Now we prompt */
+        Ext.Msg.prompt("We have important work to do.", "Enter filename.", 
+            function(btn, text) {
+                if (btn == 'ok') {
+                    yt_rpc.ExtDirectREPL.save_session(
+                        {filename:text}, handleResponse);
+                }
+            }
         );
     },
 
-    saveScript: function (b,e) { 
-        Ext.Msg.prompt("We have important work to do.", 
-        "Enter filename.", 
-        function(btn, text) {
-            if (btn == 'ok'){
-                yt_rpc.ExtDirectREPL.save_session({filename:text}, 
-                function(f, a) {
-                    if (a.result['status'] == 'SUCCESS') {
-                        var alert_text = 'Saved session to ' + 
-                        a.result['filename']
-                        Ext.Msg.alert('Success!', alert_text);
-                        var record = new logging_store.recordType(
-                            {record: alert_text });
-                        logging_store.add(record, number_log_records++);
-                    } else {
-                        Ext.Msg.alert('Always naysaying!',
-                            'Failed to save to ' + 
-                            a.result['filename'] + 
-                            '<br>Error: ' + 
-                            a.result['error']);
-                    }
-                });
-            }
-        });
+    openFile: function(b, e) {
+        alert("Not yet implemented.");
     },
 
     downloadScript: function(b, e) {
         window.open("session.py", "_top"); 
-        var record = new logging_store.recordType({
-            record: 'Saved session locally.'});
-        logging_store.add(record, number_log_records++);
+        this.application.fireEvent("logentry", 'Saved session locally.')
     },
 
     pastebinScript: function(b, e) {
@@ -86,9 +88,7 @@
                 var alert_text_rec = 'Pasted session to: ' + 
                 a.result['site']
                 Ext.Msg.alert('Pastebin', alert_text);
-                var record = new logging_store.recordType(
-                    {record: alert_text_rec });
-                logging_store.add(record, number_log_records++);
+                this.application.fireEvent("logentry", alert_text_rec);
             }
         }); 
     },
@@ -98,7 +98,7 @@
     },
 
     quitReason: function(b, e) {
-        task_runner.stop(heartbeat)
+        this.application.fireEvent("stopheartbeat");
         yt_rpc.ExtDirectREPL.shutdown({}, function(f,a) { 
         Ext.Msg.alert("Goodbye!", "Goodbye from Reason!", function() {
         window.open("http://www.google.com/", "_top");});});


diff -r c45c2fbe66a8986c28f4a2814c03640f41841761 -r 943efa19ce9ba190c5d14f345a6e029925fd00e7 yt/gui/reason/html/app/controller/PayloadDirector.js
--- a/yt/gui/reason/html/app/controller/PayloadDirector.js
+++ b/yt/gui/reason/html/app/controller/PayloadDirector.js
@@ -37,6 +37,7 @@
     init: function() {
         this.application.addListener({
             payloadreceived: {fn: this.handlePayload, scope: this},
+            stopheartbeat: {fn: this.stopHeartbeat, scope: this},
         })
         /* We also use this as our heartbeat */
         this.taskRunner = new Ext.util.TaskRunner();
@@ -63,6 +64,10 @@
                 return true;
             }
         );
-    }
+    },
+
+    stopHeartbeat: function() {
+        this.taskRunner.stopAll();
+    },
 });
 


diff -r c45c2fbe66a8986c28f4a2814c03640f41841761 -r 943efa19ce9ba190c5d14f345a6e029925fd00e7 yt/gui/reason/html/app/view/MainMenu.js
--- a/yt/gui/reason/html/app/view/MainMenu.js
+++ b/yt/gui/reason/html/app/view/MainMenu.js
@@ -36,16 +36,19 @@
       {
         text: 'Reason Menu',
         menu: [
-               {xtype: 'menuitem', text: 'Open File'},
+               {xtype: 'menuitem', text: 'Open File', id: 'openfile'},
                {xtype: 'menuitem', text: 'Open Directory', disabled: true},
                {xtype: 'menuseparator'},
-               {xtype: 'menuitem', text: 'Save Script'},
-               {xtype: 'menuitem', text: 'Download Script'},
-               {xtype: 'menuitem', text: 'Pastebin Script'},
+               {xtype: 'menuitem', text: 'Save Script',
+                id: 'savescript'},
+               {xtype: 'menuitem', text: 'Download Script',
+                id: 'downloadscript'},
+               {xtype: 'menuitem', text: 'Pastebin Script',
+                id: 'pastebinscript'},
                {xtype: 'menuseparator'},
-               {xtype:'menuitem', text: 'yt Chat'},
+               {xtype:'menuitem', text: 'yt Chat', id: 'ytchat'},
                {xtype: 'menuseparator'},
-               {xtype:'menuitem', text: 'Quit'},
+               {xtype:'menuitem', text: 'Quit', id: 'quit'},
             ],
       },
     ],



https://bitbucket.org/yt_analysis/yt/changeset/5c6e3402f91f/
changeset:   5c6e3402f91f
branch:      yt
user:        MatthewTurk
date:        2012-05-31 22:13:18
summary:     Many modifications to get widgets starting to work.  Went back and forth on the
tree proxy system, but this seems to work.  Using 'direct' as a method sort of
worked, but getting the root node was challenging since we're showing a list
that isn't quite organized like that.
affected #:  10 files

diff -r 943efa19ce9ba190c5d14f345a6e029925fd00e7 -r 5c6e3402f91f1231f1d5d7cfd35ec0ef2623328e yt/gui/reason/bottle_mods.py
--- a/yt/gui/reason/bottle_mods.py
+++ b/yt/gui/reason/bottle_mods.py
@@ -114,7 +114,7 @@
         future_route = self.api_url
         super(BottleDirectRouter, self).__init__(*args, **kwargs)
         self.__name__ = str(self.my_name)
-        route_functions[future_route] = ((), {'method':"POST"}, self)
+        route_functions[future_route] = ((), {'method':("POST", "GET")}, self)
         preroute("/resources/ext-%s-api.js" % self.api_url, method="GET")(self._myapi)
         notify_route(self)
 


diff -r 943efa19ce9ba190c5d14f345a6e029925fd00e7 -r 5c6e3402f91f1231f1d5d7cfd35ec0ef2623328e yt/gui/reason/html/app/controller/DataObjects.js
--- a/yt/gui/reason/html/app/controller/DataObjects.js
+++ b/yt/gui/reason/html/app/controller/DataObjects.js
@@ -43,35 +43,44 @@
         },
     ],
 
-
     init: function() {
         this.application.addListener({
            newdataobjects : {fn: this.refreshDataObjects, scope: this},
         });
+        this.control({
+            "#dataobjects": { itemcontextmenu:
+                function(view, rec, node, index, e) {
+                    e.preventDefault();
+                    this.application.fireEvent("showwidgets", rec, e);
+            }
+        }});
         this.callParent(arguments);
     },
 
     refreshDataObjects: function(objs) {
         console.log("Refreshing data objects");
-        var view = this.getDataObjectTree();
-        var store = this.getDataObjectsStore();
-        store.removeAll();
-        store.setRootNode({text: '', leaf: false, expanded: true});
-        var root = store.getRootNode();
+        var root = this.getDataObjectsStore().getRootNode();
+        root.removeAll();
         var pf;
         Ext.each(objs, function(o, i, os) {
             console.log("Appending " + o['name']);
             pf = root.appendChild({
-                text: o['name'],
-                objdata: o,
+                name: o.name,
+                type: o.type,
+                filename: o.filename,
+                field_list: o.field_list,
+                varname: o.varname,
                 leaf: false,
                 expanded: true,
                 iconCls: 'pf_icon'
             });
             Ext.each(o['children'], function(c, ci, cs) {
                 console.log("    Appending " + c['name']);
-                pf.appendChild({text: c['name'],
-                                objdata: c,
+                pf.appendChild({name: o.name,
+                                type: o.type,
+                                filename: o.filename,
+                                field_list: o.field_list,
+                                varname: o.varname,
                                 leaf: true,
                                 iconcls: 'data_obj'});
 


diff -r 943efa19ce9ba190c5d14f345a6e029925fd00e7 -r 5c6e3402f91f1231f1d5d7cfd35ec0ef2623328e yt/gui/reason/html/app/controller/WidgetDirector.js
--- a/yt/gui/reason/html/app/controller/WidgetDirector.js
+++ b/yt/gui/reason/html/app/controller/WidgetDirector.js
@@ -29,21 +29,50 @@
     stores: ['WidgetTypes', 'WidgetInstances'],
 
     init: function() {
-        var store = this.getWidgetTypesStore();
         Ext.iterate(Reason.controller.widgets, function(i, w, ws) {
-            if (w.prototype.widgetName == null) {return;}
-            console.log("Registering " + w.prototype.widgetName);
-            store.add({widgetname: w.prototype.widgetName,
-                       widgetclass: w});
-        });
+            Ext.require(w.getName());
+            this.registerWidget(w);
+        }, this);
         this.application.addListener({
             createwidget: {fn: this.createWidget, scope: this},
+            showwidgets: {fn: this.showWidgetMenu, scope: this},
         });
         this.callParent(arguments);
     },
 
-    createWidget: function(widgetType, dataObject) {
-        console.log("Asked to create " + widgetType);
+    registerWidget: function(w) {
+        if (w.prototype.widgetName == null) {return;}
+        console.log("Registering " + w.prototype.widgetName);
+        this.getWidgetTypesStore().add({
+                   widgetname: w.prototype.widgetName,
+                   widgetclass: w,
+                   displayname: w.prototype.displayName,
+                   pfs: w.prototype.supportsParameterFiles,
+                   objs: w.prototype.supportsDataObjects,
+        });
+    },
+
+    createWidget: function(b, e) {
+        var w = b.widget;
+        console.log("Asked to create " + b.widget.widgetName);
+        b.widget.createWidget(b.dataObj);
+    },
+
+    showWidgetMenu: function(treerecord, e) {
+        var contextMenu = Ext.create('Ext.menu.Menu', {plain: true,});
+        
+        var w;
+        examine = treerecord;
+        this.getWidgetTypesStore().each(function(record, idx) {
+            w = record.data;
+            contextMenu.add({xtype:'menuitem',
+                             text: w.displayname,
+                             handler: this.createWidget,
+                             widget: w.widgetclass,
+                             dataObj: treerecord.data,
+            });
+        }, this);
+        contextMenu.showAt(e.getXY());
     },
 
 });


diff -r 943efa19ce9ba190c5d14f345a6e029925fd00e7 -r 5c6e3402f91f1231f1d5d7cfd35ec0ef2623328e yt/gui/reason/html/app/controller/widgets/BaseWidget.js
--- a/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
+++ b/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
@@ -25,13 +25,6 @@
 
 Ext.define('Reason.controller.widgets.BaseWidget', {
     extend: 'Ext.app.Controller',
-
-    statics: {
-        widgetTypes: [],
-        register: function(widgetName, widgetClass) {
-            alert(widgetName);
-            examine = widgetClass;
-        },
-    },
-
+    supportsParameterFiles: false,
+    supportsDataObjects: false,
 });


diff -r 943efa19ce9ba190c5d14f345a6e029925fd00e7 -r 5c6e3402f91f1231f1d5d7cfd35ec0ef2623328e yt/gui/reason/html/app/controller/widgets/SampleWidget.js
--- a/yt/gui/reason/html/app/controller/widgets/SampleWidget.js
+++ b/yt/gui/reason/html/app/controller/widgets/SampleWidget.js
@@ -26,5 +26,13 @@
 Ext.define('Reason.controller.widgets.SampleWidget', {
     extend: 'Reason.controller.widgets.BaseWidget',
     widgetName: 'sample_widget',
-    statics: { something: 1, },
+    supportsDataObjects: true,
+    supportsParameterFiles: true,
+    displayName: 'Sample Widget',
+
+    statics: {
+        createWidget: function(obj) {
+            alert("Hey, being created!");
+        },
+    },
 });


diff -r 943efa19ce9ba190c5d14f345a6e029925fd00e7 -r 5c6e3402f91f1231f1d5d7cfd35ec0ef2623328e yt/gui/reason/html/app/model/DataObject.js
--- a/yt/gui/reason/html/app/model/DataObject.js
+++ b/yt/gui/reason/html/app/model/DataObject.js
@@ -24,6 +24,6 @@
 ***********************************************************************/
 
 Ext.define('Reason.model.DataObject', {
-    extent: 'Ext.data.Model',
+    extend: 'Ext.data.Model',
     fields: ['name', 'type', 'filename', 'field_list', 'varname'],
 });


diff -r 943efa19ce9ba190c5d14f345a6e029925fd00e7 -r 5c6e3402f91f1231f1d5d7cfd35ec0ef2623328e yt/gui/reason/html/app/store/DataObjects.js
--- a/yt/gui/reason/html/app/store/DataObjects.js
+++ b/yt/gui/reason/html/app/store/DataObjects.js
@@ -31,7 +31,14 @@
 
 Ext.define('Reason.store.DataObjects', {
     extend: 'Ext.data.TreeStore',
+    requires: ['Reason.model.DataObject'],
     model: 'Reason.model.DataObject',
-    data: [],
+    autoLoad: false,
+    proxy: {
+        type: 'memory',
+        reader: {
+            type: 'array',
+        }
+    },
 });
 


diff -r 943efa19ce9ba190c5d14f345a6e029925fd00e7 -r 5c6e3402f91f1231f1d5d7cfd35ec0ef2623328e yt/gui/reason/html/app/store/WidgetTypes.js
--- a/yt/gui/reason/html/app/store/WidgetTypes.js
+++ b/yt/gui/reason/html/app/store/WidgetTypes.js
@@ -32,6 +32,6 @@
 Ext.define('Reason.store.WidgetTypes', {
     extend: 'Ext.data.Store',
     id: 'widgettypes',
-    fields: ['widgetname', 'widgetclass'],
+    fields: ['widgetname', 'displayname', 'widgetclass', 'pfs', 'objs'],
     data: [],
 });


diff -r 943efa19ce9ba190c5d14f345a6e029925fd00e7 -r 5c6e3402f91f1231f1d5d7cfd35ec0ef2623328e yt/gui/reason/html/app/view/DataObjectTree.js
--- a/yt/gui/reason/html/app/view/DataObjectTree.js
+++ b/yt/gui/reason/html/app/view/DataObjectTree.js
@@ -36,18 +36,22 @@
     itemId: 'dataobjects',
     rootVisible: false,
     iconCls: 'nav',
+    displayField: 'name',
     header: false,
     root: {
         expanded: true,
         text: '',
         leaf: false,
     },
-    columns: [{
-        xtype: 'treecolumn',
-        text: 'Object',
-        sortable: false,
-        dataIndex: 'text',
-        flex: 1.0,
-    }],
+    columns: {
+        items: [ 
+            { xtype: 'treecolumn',
+              text: 'Object',
+              sortable: false,
+              dataIndex: 'name',
+              flex: 1.0,
+            },
+        ]
+    },
 });
 


diff -r 943efa19ce9ba190c5d14f345a6e029925fd00e7 -r 5c6e3402f91f1231f1d5d7cfd35ec0ef2623328e yt/gui/reason/html/app/view/MainMenu.js
--- a/yt/gui/reason/html/app/view/MainMenu.js
+++ b/yt/gui/reason/html/app/view/MainMenu.js
@@ -35,6 +35,7 @@
     items: [
       {
         text: 'Reason Menu',
+        plain: true,
         menu: [
                {xtype: 'menuitem', text: 'Open File', id: 'openfile'},
                {xtype: 'menuitem', text: 'Open Directory', disabled: true},



https://bitbucket.org/yt_analysis/yt/changeset/4e02db0e0579/
changeset:   4e02db0e0579
branch:      yt
user:        MatthewTurk
date:        2012-05-31 23:00:12
summary:     Widget creation and subsequent storage now works.  Still working through how to
get the widget creation to work, with what particular combination of statics
and factory methods to use to make it easiest to add new widgets.
affected #:  4 files

diff -r 5c6e3402f91f1231f1d5d7cfd35ec0ef2623328e -r 4e02db0e05792e5f7b6a560b8b0e372931d3f7b2 yt/gui/reason/extdirect_repl.py
--- a/yt/gui/reason/extdirect_repl.py
+++ b/yt/gui/reason/extdirect_repl.py
@@ -596,7 +596,6 @@
                                          sample_values = _tsample_values)
         from yt.funcs import YTEmptyClass
         _tpw = YTEmptyClass()
-        print "GOT TPW"
         _tpw._widget_name = 'isocontour_viewer'
         _tpw._ext_widget_id = None
         _tverts = _tiso[0].ravel().tolist()


diff -r 5c6e3402f91f1231f1d5d7cfd35ec0ef2623328e -r 4e02db0e05792e5f7b6a560b8b0e372931d3f7b2 yt/gui/reason/html/app/controller/WidgetDirector.js
--- a/yt/gui/reason/html/app/controller/WidgetDirector.js
+++ b/yt/gui/reason/html/app/controller/WidgetDirector.js
@@ -41,35 +41,51 @@
     },
 
     registerWidget: function(w) {
-        if (w.prototype.widgetName == null) {return;}
-        console.log("Registering " + w.prototype.widgetName);
+        if (w.widgetName == null) {return;}
+        console.log("Registering " + w.widgetName);
         this.getWidgetTypesStore().add({
-                   widgetname: w.prototype.widgetName,
+                   widgetname: w.widgetName,
                    widgetclass: w,
-                   displayname: w.prototype.displayName,
-                   pfs: w.prototype.supportsParameterFiles,
-                   objs: w.prototype.supportsDataObjects,
+                   displayname: w.displayName,
+                   pfs: w.supportsParameterFiles,
+                   objs: w.supportsDataObjects,
         });
     },
 
     createWidget: function(b, e) {
         var w = b.widget;
         console.log("Asked to create " + b.widget.widgetName);
-        b.widget.createWidget(b.dataObj);
+        var wi = b.widget.factory(b.dataObj);
+        examine = this;
+        this.getWidgetInstancesStore().add({
+              widgetid: wi.varname,
+              widgettype: w.widgetName,
+              widget: wi
+        });
+        examine = this;
     },
 
     showWidgetMenu: function(treerecord, e) {
         var contextMenu = Ext.create('Ext.menu.Menu', {plain: true,});
-        
+        var data = treerecord.data;
         var w;
-        examine = treerecord;
         this.getWidgetTypesStore().each(function(record, idx) {
             w = record.data;
+            examine = w;
+            if (((data.type == 'parameter_file') && (w.pfs  == false)) 
+             || ((data.type != 'parameter_file') && (w.objs == false))) {
+              return;
+            }
             contextMenu.add({xtype:'menuitem',
                              text: w.displayname,
-                             handler: this.createWidget,
+                             listeners: {
+                                click: {
+                                    fn : this.createWidget,
+                                    scope: this
+                                },
+                             },
                              widget: w.widgetclass,
-                             dataObj: treerecord.data,
+                             dataObj: data
             });
         }, this);
         contextMenu.showAt(e.getXY());


diff -r 5c6e3402f91f1231f1d5d7cfd35ec0ef2623328e -r 4e02db0e05792e5f7b6a560b8b0e372931d3f7b2 yt/gui/reason/html/app/controller/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
@@ -29,6 +29,18 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ***********************************************************************/
 
+Ext.define("Reason.controller.widgets.PlotWindow", {
+    extend: 'Reason.controller.widgets.BaseWidget',
+    supportsDataObjects: false,
+    supportsParameterFiles: true,
+    displayName: 'Do not use',
+
+    statics: {
+        createWidget: function(obj) {
+            examine = this;
+        },
+    },
+});
 
 
 var WidgetPlotWindow = function(python_varname, widget_data) {


diff -r 5c6e3402f91f1231f1d5d7cfd35ec0ef2623328e -r 4e02db0e05792e5f7b6a560b8b0e372931d3f7b2 yt/gui/reason/html/app/controller/widgets/SampleWidget.js
--- a/yt/gui/reason/html/app/controller/widgets/SampleWidget.js
+++ b/yt/gui/reason/html/app/controller/widgets/SampleWidget.js
@@ -25,14 +25,19 @@
 
 Ext.define('Reason.controller.widgets.SampleWidget', {
     extend: 'Reason.controller.widgets.BaseWidget',
-    widgetName: 'sample_widget',
-    supportsDataObjects: true,
-    supportsParameterFiles: true,
-    displayName: 'Sample Widget',
 
     statics: {
-        createWidget: function(obj) {
-            alert("Hey, being created!");
+        widgetName: 'sample_widget',
+        supportsDataObjects: true,
+        supportsParameterFiles: true,
+        displayName: 'Sample Widget',
+        factory: function(obj) {
+            return new this({varname:obj.varname});
         },
     },
+
+    config: {
+        varname: null,
+    },
+
 });



https://bitbucket.org/yt_analysis/yt/changeset/2f2a2c78ee9d/
changeset:   2f2a2c78ee9d
branch:      yt
user:        MatthewTurk
date:        2012-06-01 00:08:31
summary:     Base widget now supports the new TemplateContainer class.
affected #:  2 files

diff -r 4e02db0e05792e5f7b6a560b8b0e372931d3f7b2 -r 2f2a2c78ee9da76594e3cc91cbebea11287b3c57 yt/gui/reason/html/app/controller/widgets/BaseWidget.js
--- a/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
+++ b/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
@@ -23,8 +23,24 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ***********************************************************************/
 
+Ext.require("Reason.templates.TemplateContainer");
+
 Ext.define('Reason.controller.widgets.BaseWidget', {
     extend: 'Ext.app.Controller',
     supportsParameterFiles: false,
     supportsDataObjects: false,
+    templateManager: null,
+    templates: {},
+
+    constructor: function() {
+        this.templateManager = Ext.create(
+            "Reason.templates.TemplateContainer",
+            { templates: this.templates }
+        );
+        this.callParent(arguments);
+    },
+
+    execute: function(tpl) {
+        tpl.apply(this);
+    },
 });


diff -r 4e02db0e05792e5f7b6a560b8b0e372931d3f7b2 -r 2f2a2c78ee9da76594e3cc91cbebea11287b3c57 yt/gui/reason/html/app/templates/TemplateContainer.js
--- /dev/null
+++ b/yt/gui/reason/html/app/templates/TemplateContainer.js
@@ -0,0 +1,52 @@
+/**********************************************************************
+The Plot Window Widget
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define("Reason.templates.TemplateContainer", {
+    constructor: function(config) {
+        this.initConfig(config);
+        this.callParent(arguments);
+    },
+
+    config: {
+        templates : {},
+    },
+
+    applyObject: function(obj) {
+        var applied = {};
+        var tpl;
+        Ext.iterate(this.getTemplates(), function(k, v, o){
+            tpl = new Ext.XTemplate(v);
+            examine = {tpl: tpl, v:v, k:k};
+            applied[k] = tpl.apply(obj);
+        });
+        return applied;
+    }
+});



https://bitbucket.org/yt_analysis/yt/changeset/eefdb974826f/
changeset:   eefdb974826f
branch:      yt
user:        MatthewTurk
date:        2012-06-01 00:40:00
summary:     Can now be prompted for widget creation for plot windows and projections.
Still some work to do for cleaning it up, and possibly even splitting it up
into multiple files.
affected #:  4 files

diff -r 2f2a2c78ee9da76594e3cc91cbebea11287b3c57 -r eefdb974826f24f8d619e34aef8ed071194d7954 yt/gui/reason/html/app.js
--- a/yt/gui/reason/html/app.js
+++ b/yt/gui/reason/html/app.js
@@ -91,6 +91,7 @@
               }
             ]
         });
+        this.fireEvent("allowinput");
     },
     controllers : [
         'Logging',


diff -r 2f2a2c78ee9da76594e3cc91cbebea11287b3c57 -r eefdb974826f24f8d619e34aef8ed071194d7954 yt/gui/reason/html/app/controller/WidgetDirector.js
--- a/yt/gui/reason/html/app/controller/WidgetDirector.js
+++ b/yt/gui/reason/html/app/controller/WidgetDirector.js
@@ -25,7 +25,9 @@
 
 Ext.define('Reason.controller.WidgetDirector', {
     extend: 'Ext.app.Controller',
-    requires: ["Reason.controller.widgets.SampleWidget"],
+    requires: ["Reason.controller.widgets.SampleWidget",
+               "Reason.controller.widgets.PlotWindow",
+    ],
     stores: ['WidgetTypes', 'WidgetInstances'],
 
     init: function() {
@@ -55,14 +57,8 @@
     createWidget: function(b, e) {
         var w = b.widget;
         console.log("Asked to create " + b.widget.widgetName);
-        var wi = b.widget.factory(b.dataObj);
-        examine = this;
-        this.getWidgetInstancesStore().add({
-              widgetid: wi.varname,
-              widgettype: w.widgetName,
-              widget: wi
-        });
-        examine = this;
+        var store = this.getWidgetInstancesStore();
+        b.widget.preCreation(b.dataObj);
     },
 
     showWidgetMenu: function(treerecord, e) {


diff -r 2f2a2c78ee9da76594e3cc91cbebea11287b3c57 -r eefdb974826f24f8d619e34aef8ed071194d7954 yt/gui/reason/html/app/controller/widgets/BaseWidget.js
--- a/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
+++ b/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
@@ -43,4 +43,13 @@
     execute: function(tpl) {
         tpl.apply(this);
     },
+
+    prepHandler: function(fn, en, scope) {
+        var conf = {};
+        if (en == null) { en = 'click'; }
+        if (scope == null) { scope = this; }
+        examine = {en:en, scope: scope};
+        conf[en] = { fn: fn, scope: scope };
+        return conf
+    },
 });


diff -r 2f2a2c78ee9da76594e3cc91cbebea11287b3c57 -r eefdb974826f24f8d619e34aef8ed071194d7954 yt/gui/reason/html/app/controller/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
@@ -31,19 +31,39 @@
 
 Ext.define("Reason.controller.widgets.PlotWindow", {
     extend: 'Reason.controller.widgets.BaseWidget',
-    supportsDataObjects: false,
-    supportsParameterFiles: true,
-    displayName: 'Do not use',
+    templates: {
+        pwt: 'Projection Details for {name}',
+        swt: 'Slice Details for {name}',
+    },
 
-    statics: {
-        createWidget: function(obj) {
-            examine = this;
-        },
+    acceptResults: function(payload) {
+        this.image_panel.el.dom.src = "data:image/png;base64," + payload['image_data'];
+        this.zoom_scroll.setValue(0, payload['zoom'], true);
+        this.metadata_panel.update(payload['metadata_string']);
+        metadata_string = payload['metadata_string'];
+        ticks.removeAll();
+        Ext.each(payload['ticks'], function(tick, index) {
+            ticks.add({xtype:'panel',
+                       width: 10, height:1,
+                       style: 'background-color: #000000;',
+                       html:' ',
+                       x:0, y: 10 + tick[0]});
+            ticks.add({xtype:'panel',
+                       width: 90, height:15,
+                       border: false,
+                       style: 'font-family: "Inconsolata", monospace;' +
+                              'font-size: 12px;',
+                       html: '' + tick[2] + '',
+                       x:12, y: 4 + tick[0]});
+        });
+        if (payload['colorbar_image'] != null) {
+            colorbar.el.dom.src = "data:image/png;base64," +
+                payload['colorbar_image'];
+        }
+        ticks.doLayout();
     },
-});
 
-
-var WidgetPlotWindow = function(python_varname, widget_data) {
+    createWindow: function() {
     this.id = python_varname;
     this.widget_data = widget_data;
     this.print_python = function(b, e) {
@@ -738,7 +758,90 @@
 
     yt_rpc.ExtDirectREPL.execute(
         {code:python_varname + '.zoom(1.0)', hide:true},
-        cell_finished);
-}
+        CELl_finished);
+    },
 
-widget_types['plot_window'] = WidgetPlotWindow;
+    statics: {
+        widgetName: 'plotwindow',
+        supportsDataObjects: false,
+        supportsParameterFiles: true,
+        displayName: 'Do not use',
+        preCreation: function(obj) {
+            var widget = Ext.create(this.getName())
+            var ts = widget.templateManager.applyObject(obj);
+            var win;
+            function makeProj(b, e) {
+                var axis = Ext.get("axis").getValue();
+                var field = Ext.get("field").getValue();
+                var weight = Ext.get("weightField").getValue();
+                var onmax = Ext.get("max_dens").getValue();
+                reason.fireEvent("disableinput");
+                yt_rpc.ExtDirectREPL.create_proj({
+                        pfname: obj.varname,
+                        axis: axis, field: field, weight: weight,
+                        onmax: onmax},
+                      Ext.emptyFn);
+                Ext.WindowManager.getActive().close();
+            }
+            win = new Ext.Window({
+                layout: 'fit',
+                width: 370,
+                height: 220,
+                modal: true,
+                resizable: false,
+                draggable: false,
+                border: false,
+                title: ts.pwt,
+                items: [{
+                    xtype: 'form',
+                    labelWidth:80,
+                    frame:true,
+                    items: [{
+                        xtype:'combo',
+                        fieldLabel: 'Axis',
+                        id: 'axis',
+                        store:['X','Y','Z'],
+                        width: 230,
+                        allowBlank:false,
+                        triggerAction: 'all',
+                        value: 'X',
+                    },{
+                        xtype:'checkbox',
+                        fieldLabel: 'Center on Max',
+                        id: 'max_dens',
+                        width: 90,
+                        allowBlank:false,
+                    },{
+                        xtype:'combo',
+                        fieldLabel: 'Field',
+                        id: 'field',
+                        store:obj.field_list,
+                        width: 230,
+                        allowBlank:false,
+                        triggerAction: 'all',
+                        value: 'Density'
+                    },{
+                        xtype:'combo',
+                        fieldLabel: 'Weight Field',
+                        id: 'weightField',
+                        store:['None'].concat(obj.field_list),
+                        width: 230,
+                        allowBlank:false,
+                        triggerAction: 'all',
+                        value: 'None'
+                    }],
+                    buttons: [
+                        {
+                            text: 'Project',
+                            listeners: widget.prepHandler(makeProj),
+                        },{
+                            text: 'Cancel',
+                            handler: function(){win.close();},
+                        }
+                    ]
+                }]
+            });
+            win.show();
+        },
+    },
+});



https://bitbucket.org/yt_analysis/yt/changeset/58e82a183780/
changeset:   58e82a183780
branch:      yt
user:        MatthewTurk
date:        2012-06-01 03:25:34
summary:     Initial split and import of the views for the PlotWindow.
affected #:  2 files

diff -r eefdb974826f24f8d619e34aef8ed071194d7954 -r 58e82a1837808afdb1f8fdd9c14556e3da2138b9 yt/gui/reason/html/app/view/widgets/PlotWindow.js
--- /dev/null
+++ b/yt/gui/reason/html/app/view/widgets/PlotWindow.js
@@ -0,0 +1,393 @@
+/**********************************************************************
+The Plot Window Widget View
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define("Reason.view.widgets.PlotWindow", {
+    extend: 'Ext.panel.Panel',
+    title: 'This should not be visible.',
+    alias: 'widget.plotwindow',
+    iconCls: 'graph',
+    autoScroll: true,
+    layout:'absolute',
+    width: '100%',
+    height: '100%',
+    closable: true,
+
+    items: [ 
+        { xtype:'panel',
+          id: 'image_panel',
+          autoEl: {
+                tag: 'img',
+                id: "mainImage",
+                width: 400,
+                height: 400,
+                draggable: false,
+            },
+            x: 100,
+            y: 10,
+            width: 400,
+            height: 400,
+            draggable: false,
+        }, {
+            xtype:'panel',
+            id: 'colorbar',
+            autoEl: {
+                tag: 'img',
+                id: 'cb',
+                src: '',
+                width: 28,
+                height: 398,
+                style: 'border: 1px solid #000000;',
+            },
+            x: 510,
+            y: 10,
+            width: 30,
+            height: 400,
+        }, {
+            xtype: 'panel',
+            id: 'ticks',
+            layout: 'absolute',
+            y: 0,
+            x: 540,
+            width: 100,
+            height: 420,
+            items : [],
+            border: false,
+        }, {   xtype: 'multislider',
+            id: 'slider',
+            minValue: 0,
+            maxValue: 100,
+            increment: 0.1,
+            x: 100, y: 410,
+            width: 400,
+        },{
+            xtype: 'combo',
+            text: 'Field',
+            x: 100,
+            y: 435,
+            width: 400,
+            store: [],
+            value: '',
+            editable: false,
+            triggerAction: 'all',
+            validateOnBlur: false,
+        }, {
+        /* the single buttons for 10% pan*/
+            xtype:'button',
+            iconCls: 'singleuparrow',
+            id: 'singleuparrow',
+            //text: 'North',
+            x: 40,
+            y: 10,
+        }, {
+            xtype:'button',
+            iconCls: 'singlerightarrow',
+            id: 'singlerightarrow',
+            //text:'East',
+            x : 60,
+            y : 30,
+        }, {
+            xtype:'button',
+            iconCls: 'singledownarrow',
+            id: 'singledownarrow',
+            //text: 'South',
+            x: 40,
+            y: 50,
+        }, {
+            xtype: 'button',
+            iconCls: 'singleleftarrow',
+            id: 'singleleftarrow',
+            //text: 'West',
+            x: 20,
+            y: 30,
+        }, 
+        /* the double buttons for 50% pan*/
+        {
+            xtype:'button',
+            iconCls: 'doubleuparrow',
+            id:'doubleuparrow',
+            //text: 'North',
+            x: 40,
+            y: 80,
+        }, {
+            xtype:'button',
+            iconCls: 'doublerightarrow',
+            id:'doublerightarrow',
+            //text:'East',
+            x : 60,
+            y : 100,
+        }, {
+            xtype:'button',
+            iconCls: 'doubledownarrow',
+            //text: 'South',
+            id: 'doubledownarrow',
+            x: 40,
+            y: 120,
+        }, {
+            xtype: 'button',
+            iconCls: 'doubleleftarrow',
+            id: 'doubleleftarrow',
+            //text: 'West',
+            x: 20,
+            y: 100,
+        },
+        /* Now the zoom buttons */
+        {
+            xtype: 'button',
+            text: 'Zoom In 10x',
+            id: "zoom10x",
+            x: 10,
+            y: 160,
+            width: 80,
+        },{
+            xtype: 'button',
+            text: 'Zoom In 2x',
+            id: "zoom2x",
+            x: 10,
+            y: 185,
+            width: 80,
+        },{
+            xtype: 'button',
+            text: 'Zoom Out 2x',
+            id:'zoomout2x',
+            x: 10,
+            y: 210,
+            width: 80,
+        },{
+            xtype: 'button',
+            text: 'Zoom Out 10x',
+            id:'zoomout10x',
+            x: 10,
+            y: 235,
+            width: 80,
+        },{
+            xtype: 'button',
+            text: 'Upload Image',
+            x: 10,
+            y: 285,
+            width: 80,
+            tooltip: "Upload the current image to " +
+                     "<a href='http://imgur.com'>imgur.com</a>",
+        },{
+            xtype: 'button',
+            text: 'Pannable Map',
+            x: 10,
+            y: 335,
+            width: 80,
+            tooltip: "Open a pannable map in a new tab",
+        },{
+            xtype: 'panel',
+            layout: 'vbox',
+            id: 'rhs_panel',
+            width: 250,
+            height: 460,
+            x: 690, y: 10,
+            layoutConfig: {
+                align: 'stretch',
+                pack: 'start',
+            },
+            items: [
+                {
+                  xtype: 'panel',
+                  title: 'Plot MetaData',
+                  id: 'metadata',
+                  style: {fontFamily: '"Inconsolata", monospace'},
+                  html: 'Welcome to the Plot Window.',
+                  height: 200,
+                }, {
+                  xtype: 'tabpanel',
+                  id: 'editor_panel',
+                  flex: 1,
+                  activeTab: 0,
+                  items: [
+                {
+                  xtype: 'panel',
+                  title: 'Plot Editor',
+                  id: 'plot_edit',
+                  style: {fontFamily: '"Inconsolata", monospace'},
+                  layout: 'absolute',
+                  flex: 1,
+                  items : [
+                     {
+                       x: 10,
+                       y: 20,
+                       width: 70,
+                       xtype: 'label',
+                       text: 'Display',
+                     },
+                     {
+                       x: 80,
+                       y: 20,
+                       width : 80,
+                       xtype: 'combo',
+                       editable: false,
+                       triggerAction: 'all',
+                       validateOnBlur: false,
+                       store: ['log10', 'linear'],
+                       value: 'linear',
+                     },
+                     {
+                       x: 10,
+                       y: 60,
+                       width: 70,
+                       xtype: 'label',
+                       text: 'Colormap',
+                     },
+                     {
+                       x: 80,
+                       y: 60,
+                       width : 140,
+                       xtype: 'combo',
+                       editable: false,
+                       triggerAction: 'all',
+                       validateOnBlur: false,
+                       store: ['algae', 'RdBu', 'gist_stern',  
+                               'hot', 'jet', 'kamae', 
+                                'B-W LINEAR', 'BLUE',
+                                'GRN-RED-BLU-WHT', 'RED TEMPERATURE',
+                                'BLUE', 'STD GAMMA-II', 'PRISM',
+                                'RED-PURPLE', 'GREEN', 'GRN',
+                                'GREEN-PINK', 'BLUE-RED', '16 LEVEL',
+                                'RAINBOW', 'STEPS', 'STERN SPECIAL',
+                                'Haze', 'Blue - Pastel - Red',
+                                'Pastels', 'Hue Sat Lightness 1',
+                                'Hue Sat Lightness 2', 'Hue Sat Value 1',
+                                'Hue Sat Value 2', 'Purple-Red + Stripes',
+                                'Beach', 'Mac Style', 'Eos A', 'Eos B',
+                                'Hardcandy', 'Nature', 'Ocean', 'Peppermint',
+                                'Plasma', 'Blue-Red', 'Rainbow', 'Blue Waves',
+                                'Volcano', 'Waves', 'Rainbow18',
+                                'Rainbow + white', 'Rainbow + black'],
+                       value: 'algae',
+                     }
+                  ]
+                }, {
+                  xtype: 'panel',
+                  title: 'Contours',
+                  id: 'contour_edit',
+                  style: {fontFamily: '"Inconsolata", monospace'},
+                  layout: 'absolute',
+                  flex: 1,
+                  items : [
+                     {
+                       x: 10,
+                       y: 20,
+                       width: 70,
+                       xtype: 'label',
+                       text: 'Field',
+                     }, {
+                       x: 80,
+                       y: 20,
+                       width : 160,
+                       xtype: 'combo',
+                       editable: false,
+                       id: 'field',
+                       triggerAction: 'all',
+                       validateOnBlur: false,
+                       value: '',
+                       store: [],
+                     }, {
+                       x: 10,
+                       y: 60,
+                       width: 70,
+                       xtype: 'label',
+                       text: 'Levels',
+                     }, {
+                       x: 80,
+                       y: 60,
+                       width : 160,
+                       xtype: 'slider',
+                       id: 'ncont',
+                       minValue: 0,
+                       maxValue: 10,
+                       value: 5,
+                       increment: 1,
+                       /*plugins: [ {ptype: 'slidertip'} ],*/
+                     }, {
+                       x: 10,
+                       y: 100,
+                       width: 70,
+                       xtype: 'label',
+                       text: 'Logspaced',
+                     }, {
+                       x: 80,
+                       y: 100,
+                       width : 160,
+                       xtype: 'checkbox',
+                       id: 'logit',
+                       checked: true,
+                     }, {
+                       x: 10,
+                       y: 180,
+                       width: 80,
+                       xtype: 'button',
+                       text: 'Apply',
+                     }
+                  ]
+                }, {
+                  xtype: 'panel',
+                  title: 'Velocity Vectors',
+                  id: 'vector_edit',
+                  style: {fontFamily: '"Inconsolata", monospace'},
+                  layout: 'absolute',
+                  flex: 1,
+                  items : [
+                     {
+                       x: 10,
+                       y: 60,
+                       width: 70,
+                       xtype: 'label',
+                       text: 'Skip Factor',
+                     }, {
+                       x: 80,
+                       y: 60,
+                       width : 160,
+                       xtype: 'slider',
+                       id: 'skip',
+                       minValue: 1,
+                       maxValue: 64,
+                       value: 32,
+                       increment: 1,
+                       /*plugins: [ {ptype: 'slidertip'} ],*/
+                     }, {
+                       x: 10,
+                       y: 180,
+                       width: 80,
+                       xtype: 'button',
+                       text: 'Apply',
+                     }
+                  ]
+                }
+                ] } /* tabpanel items and entry */
+                ]
+        }
+    ],
+});
+


diff -r eefdb974826f24f8d619e34aef8ed071194d7954 -r 58e82a1837808afdb1f8fdd9c14556e3da2138b9 yt/gui/reason/html/app/view/widgets/PlotWindowCreator.js
--- /dev/null
+++ b/yt/gui/reason/html/app/view/widgets/PlotWindowCreator.js
@@ -0,0 +1,90 @@
+/**********************************************************************
+The Plot Window Widget
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define("Reason.view.widgets.PlotWindowCreator", {
+    extend: 'Ext.window.Window',
+    alias: 'widget.plotwindowcreator',
+    layout: 'fit',
+    width: 370,
+    height: 220,
+    modal: true,
+    resizable: false,
+    draggable: false,
+    border: false,
+    title: "You shouldn't see this.",
+    
+    items: [{ xtype: 'form',
+              labelWidth:80,
+              frame:true,
+              items: [{
+                  xtype:'combo',
+                  fieldLabel: 'Axis',
+                  id: 'axis',
+                  store:['X','Y','Z'],
+                  width: 230,
+                  allowBlank:false,
+                  triggerAction: 'all',
+                  value: 'X',
+              },{
+                  xtype:'checkbox',
+                  fieldLabel: 'Center on Max',
+                  id: 'max_dens',
+                  width: 90,
+                  allowBlank:false,
+              },{
+                  xtype:'combo',
+                  fieldLabel: 'Field',
+                  id: 'field',
+                  store: [],
+                  width: 230,
+                  allowBlank:false,
+                  triggerAction: 'all',
+                  value: 'Density'
+              },{
+                  xtype:'combo',
+                  fieldLabel: 'Weight Field',
+                  itemId: 'weightField',
+                  store: ['None'],
+                  width: 230,
+                  allowBlank:false,
+                  triggerAction: 'all',
+                  value: 'None'
+              }],
+              buttons: [
+                  {
+                      text: 'Project', id: 'create',
+                  },{
+                      text: 'Cancel', id: 'cancel',
+                  }
+              ]
+    }],
+});
+



https://bitbucket.org/yt_analysis/yt/changeset/1d175c797502/
changeset:   1d175c797502
branch:      yt
user:        MatthewTurk
date:        2012-06-01 03:46:03
summary:     This allows the PlotWindow tab to render correctly.
affected #:  1 file

diff -r 58e82a1837808afdb1f8fdd9c14556e3da2138b9 -r 1d175c79750299573316b33dbf34864b2f40795b yt/gui/reason/html/app/view/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/view/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/view/widgets/PlotWindow.js
@@ -35,41 +35,30 @@
     alias: 'widget.plotwindow',
     iconCls: 'graph',
     autoScroll: true,
-    layout:'absolute',
+    layout: 'absolute',
     width: '100%',
     height: '100%',
     closable: true,
 
     items: [ 
-        { xtype:'panel',
+        { xtype:'image',
           id: 'image_panel',
-          autoEl: {
-                tag: 'img',
-                id: "mainImage",
-                width: 400,
-                height: 400,
-                draggable: false,
-            },
-            x: 100,
-            y: 10,
-            width: 400,
-            height: 400,
-            draggable: false,
+          src: 'nothing.png',
+          draggable: false,
+          x: 100,
+          y: 10,
+          width: 400,
+          height: 400,
+          draggable: false,
         }, {
-            xtype:'panel',
+            xtype:'image',
             id: 'colorbar',
-            autoEl: {
-                tag: 'img',
-                id: 'cb',
-                src: '',
-                width: 28,
-                height: 398,
-                style: 'border: 1px solid #000000;',
-            },
+            src: 'nothing.png',
+            style: 'border: 1px solid #000000;',
             x: 510,
             y: 10,
-            width: 30,
-            height: 400,
+            width: 28,
+            height: 398,
         }, {
             xtype: 'panel',
             id: 'ticks',



https://bitbucket.org/yt_analysis/yt/changeset/7e8979ad9a7a/
changeset:   7e8979ad9a7a
branch:      yt
user:        MatthewTurk
date:        2012-06-01 06:04:38
summary:     Implemented a generic mechanism for linking templates, with evaluation, to
actions in a widget.  Removed key map for now.
affected #:  4 files

diff -r 1d175c79750299573316b33dbf34864b2f40795b -r 7e8979ad9a7aeb980243b9b885febdb559a64fd5 yt/gui/reason/html/app/controller/widgets/BaseWidget.js
--- a/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
+++ b/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
@@ -31,6 +31,7 @@
     supportsDataObjects: false,
     templateManager: null,
     templates: {},
+    executionTriggers: [],
 
     constructor: function() {
         this.templateManager = Ext.create(
@@ -40,16 +41,33 @@
         this.callParent(arguments);
     },
 
-    execute: function(tpl) {
-        tpl.apply(this);
+    getExecuteFunction: function(ww, templateName) {
+        var tpl = new Ext.XTemplate(
+            this.templateManager.getTemplates()[templateName]);
+        var args = {};
+        function ev() {
+            Ext.each(arguments, function(v, i) {
+                args["a" + i] = arguments[i];
+            });
+            args['widget'] = ww;
+            yt_rpc.ExtDirectREPL.execute({
+                code: tpl.apply(args),
+                hide: true}, Ext.emptyFn);
+        };
+        return ev;
     },
 
-    prepHandler: function(fn, en, scope) {
-        var conf = {};
-        if (en == null) { en = 'click'; }
-        if (scope == null) { scope = this; }
-        examine = {en:en, scope: scope};
-        conf[en] = { fn: fn, scope: scope };
-        return conf
+    applyExecuteHandlers: function(ww) {
+        var conf;
+        function ef(id, ename, tpl) {
+            conf = {}
+            conf[ename] = this.getExecuteFunction(ww, tpl);
+            console.log("Adding " + ename + " " + id);
+            ww.query(id)[0].on(conf);
+        };
+        Ext.each(this.executionTriggers, function(trigger) {
+            ef.call(this, trigger[0], trigger[1], trigger[2]);
+        }, this);
     },
+
 });


diff -r 1d175c79750299573316b33dbf34864b2f40795b -r 7e8979ad9a7aeb980243b9b885febdb559a64fd5 yt/gui/reason/html/app/controller/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
@@ -31,12 +31,67 @@
 
 Ext.define("Reason.controller.widgets.PlotWindow", {
     extend: 'Reason.controller.widgets.BaseWidget',
+    requires: ['Reason.view.widgets.PlotWindowCreator',
+               'Reason.view.widgets.PlotWindow'],
     templates: {
         pwt: 'Projection Details for {name}',
         swt: 'Slice Details for {name}',
+        scrollZoom: '{widget.varname}.scroll_zoom({a1})',
+        fieldChange: '{widget.varname}.set_current_field("{a1.data[\'field1\']}")',
+        singleUpArrow:    '{widget.varname}.pan_rel(( 0.0, -0.1))',
+        singleRightArrow: '{widget.varname}.pan_rel(( 0.1,  0.0))',
+        singleDownArrow:  '{widget.varname}.pan_rel(( 0.0   0.1))',
+        singleLeftArrow:  '{widget.varname}.pan_rel((-0.1,  0.0))',
+        doubleUpArrow:    '{widget.varname}.pan_rel(( 0.0, -0.5))',
+        doubleRightArrow: '{widget.varname}.pan_rel(( 0.5,  0.0))',
+        doubleDownArrow:  '{widget.varname}.pan_rel(( 0.0   0.5))',
+        doubleLeftArrow:  '{widget.varname}.pan_rel((-0.5,  0.0))',
+        zoomIn10x:  '{widget.varname}.zoom(10.0)',
+        zoomIn2x:   '{widget.varname}.zoom( 2.0)',
+        zoomOut10x: '{widget.varname}.zoom( 0.1)',
+        zoomOut2x:  '{widget.varname}.zoom( 0.5)',
+        adjustTransform: '{widget.varname}.set_transform(' +
+                         '{widget.varname}._current_field, ' +
+                         '"{a1.data[\'field1\']}")',
+        adjustColormap:  '{widget.varname}.set_cmap(' +
+                         '{widget.varname}._current_field, ' +
+                         '"{a1.data[\'field1\']}")',
+        adjustContours:  '{widget.varname}.set_contour_info(' +
+                         '"{widget.getContourField().getValue()}",' +
+                         ' {widget.getNcont().getValue()},' +
+                         ' {widget.getLogit().getValue():capitalize})',
+        adjustVectors:   '{widget.varname}.set_vector_info(' +
+                         '{widget.getVectorSkip()})',
     },
 
-    acceptResults: function(payload) {
+    widgetTriggers: [
+        ['upload_image'],
+        ['pannable_map'],
+        ['clickanddrag'],
+    ],
+
+    executionTriggers: [
+        ['#slider', 'changecomplete', 'scrollZoom'],
+        ['#fieldSelector', 'select', 'fieldChange'],
+        ['#singleuparrow', 'click', 'singleUpArrow'],
+        ['#singlerightarrow', 'click', 'singleRightArrow'],
+        ['#singledownarrow', 'click', 'singleDownArrow'],
+        ['#singleleftarrow', 'click', 'singleLeftArrow'],
+        ['#doubleuparrow', 'click', 'doubleUpArrow'],
+        ['#doublerightarrow', 'click', 'doubleRightArrow'],
+        ['#doubledownarrow', 'click', 'doubleDownArrow'],
+        ['#doubleleftarrow', 'click', 'doubleLeftArrow'],
+        ['#zoomin10x', 'click', 'zoomIn10x'],
+        ['#zoomin2x', 'click', 'zoomIn2x'],
+        ['#zoomout10x', 'click', 'zoomOut10x'],
+        ['#zoomout2x', 'click', 'zoomOut2x'],
+        ['#transform', 'select', 'adjustTransform'],
+        ['#colormap', 'select', 'adjustColormap'],
+        ['#contourapply', 'click', 'adjustContours'],
+        ['#vectorsapply', 'click', 'adjustVectors'],
+    ],
+
+    applyPayload: function(payload, instance) {
         this.image_panel.el.dom.src = "data:image/png;base64," + payload['image_data'];
         this.zoom_scroll.setValue(0, payload['zoom'], true);
         this.metadata_panel.update(payload['metadata_string']);
@@ -63,713 +118,15 @@
         ticks.doLayout();
     },
 
-    createWindow: function() {
-    this.id = python_varname;
-    this.widget_data = widget_data;
-    this.print_python = function(b, e) {
-        yt_rpc.ExtDirectREPL.execute(
-            {code:'print "' + python_varname + '"',
-             hide:true},
-            function(f, a) {alert(a.result['output']);}
-        );
-    }
-
-    this.widget_keys = new Ext.KeyMap(document, [
-        {key: 'z',
-         shift: false,
-         fn: function(){
-               control_panel.get("zoom2x").handler();
-            }
-        },
-        {key: 'Z',
-         shift: true,
-         fn: function(){
-               control_panel.get("zoom10x").handler();
-            }
-        },
-        {key: 'x',
-         shift: false,
-         fn: function(){
-               control_panel.get("zoomout2x").handler();
-            }
-        },
-        {key: 'X',
-         shift: true,
-         fn: function(){
-               control_panel.get("zoomout10x").handler();
-            }
-        },
-        {key: 'k',
-         shift: false,
-         fn: function(){
-               control_panel.get("singleuparrow").handler();
-            }
-        },
-        {key: 'j',
-         shift: false,
-         fn: function(){
-               control_panel.get("singledownarrow").handler();
-            }
-        },
-        {key: 'h',
-         shift: false,
-         fn: function(){
-               control_panel.get("singleleftarrow").handler();
-            }
-        },
-        {key: 'l',
-         shift: false,
-         fn: function(){
-               control_panel.get("singlerightarrow").handler();
-            }
-        },
-        {key: 'K',
-         shift: true,
-         fn: function(){
-               control_panel.get("doubleuparrow").handler();
-            }
-        },
-        {key: 'J',
-         shift: true,
-         fn: function(){
-               control_panel.get("doubledownarrow").handler();
-            }
-        },
-        {key: 'H',
-         shift: true,
-         fn: function(){
-               control_panel.get("doubleleftarrow").handler();
-            }
-        },
-        {key: 'L',
-         shift: true,
-         fn: function(){
-               control_panel.get("doublerightarrow").handler();
-            }
-        },
-    ]);
-    var widget_keys = this.widget_keys;
-    widget_keys.disable();
-    widget_keys.varname = python_varname;
-
-    viewport.get("center-panel").add(
-        {
-            xtype: 'panel',
-            id: "pw_" + this.id,
-            title: widget_data['title'],
-            iconCls: 'graph',
-            autoScroll: true,
-            layout:'absolute',
-            closable: true,
-            listeners: {activate: function(p){
-                                widget_keys.enable();
-                            },
-                        deactivate: function(p){
-                                widget_keys.disable();
-                            }
-                        },
-            items: [ 
-                {
-                    xtype:'panel',
-                    id: 'image_panel_' + this.id,
-                    autoEl: {
-                        tag: 'img',
-                        id: "img_" + this.id,
-                        width: 400,
-                        height: 400,
-                        draggable: false,
-                    },
-                    x: 100,
-                    y: 10,
-                    width: 400,
-                    height: 400,
-                    draggable: false,
-                    listeners: {
-                        afterrender: function(c){
-                            c.el.on('click', function(e){
-                                if (e.ctrlKey == false) return;
-                                xy = e.getXY();
-                                cc = python_varname + ".image_recenter(" 
-                                    + (xy[0] - c.el.dom.x) + ", "
-                                    + (xy[1] - c.el.dom.y) + ", "
-                                    + c.el.dom.width + ", "
-                                    + c.el.dom.height + ")";
-                                yt_rpc.ExtDirectREPL.execute(
-                                {code:cc, hide:true}, cell_finished); 
-                            });
-                            c.el.on('mousedown', function(e){
-                                c.drag_start = true;
-                                c.drag_start_pos = e.getXY();
-                            });
-                            c.el.on('mouseup', function(e){
-                                c.drag_start = false;
-                                drag_stop = e.getXY();
-                                delta_x = drag_stop[0] - c.drag_start_pos[0];
-                                delta_y = drag_stop[1] - c.drag_start_pos[1];
-                                if (((delta_x < -10) || (delta_x > 10)) ||
-                                    ((delta_y < -10) || (delta_y > 10))) {
-                                    rel_x = -delta_x / 400;
-                                    rel_y = -delta_y / 400;
-                                    cc = python_varname + '.pan_rel((' + 
-                                        rel_x + ',' + rel_y + '))';
-                                    yt_rpc.ExtDirectREPL.execute(
-                                    {code:cc, hide:true}, cell_finished); 
-                                }
-                            });
-                        }
-                    }
-                }, {
-                    xtype:'panel',
-                    id: 'colorbar_' + python_varname,
-                    autoEl: {
-                        tag: 'img',
-                        id: "cb_" + python_varname,
-                        src: "data:image/png;base64," +
-                             widget_data['colorbar'],
-                        width: 28,
-                        height: 398,
-                        style: 'border: 1px solid #000000;',
-                    },
-                    x: 510,
-                    y: 10,
-                    width: 30,
-                    height: 400,
-                }, {
-                    xtype: 'panel',
-                    id: 'ticks_' + python_varname,
-                    layout: 'absolute',
-                    y: 0,
-                    x: 540,
-                    width: 100,
-                    height: 420,
-                    items : [],
-                    border: false,
-                }, {   xtype: 'multislider',
-                    id: 'slider_' + python_varname,
-                    minValue: 0,
-                    maxValue: 100,
-                    increment: 0.1,
-                    x: 100, y: 410,
-                    width: 400,
-                    listeners: {
-                        /* Only changecomplete; don't want too many render
-                        events */
-                        changecomplete: function(slider, newValue, thumb) {
-                            yt_rpc.ExtDirectREPL.execute(
-                                {code:python_varname + ".scroll_zoom(" +
-                                      newValue + ")",
-                                 hide:true}, cell_finished);
-                        }
-                    }
-                },{
-                    xtype: 'combo',
-                    text: 'Field',
-                    x: 100,
-                    y: 435,
-                    width: 400,
-                    store:widget_data['fields'],
-                    value:widget_data['initial_field'],
-                    editable: false,
-                    triggerAction: 'all',
-                    validateOnBlur: false,
-                    listeners: {select: function(combo, record, index) {
-                        var newValue = record.data['field1'];
-                        yt_rpc.ExtDirectREPL.execute(
-                            {code:python_varname + '.set_current_field("' +
-                                newValue + '")', hide:false},
-                            cell_finished);
-                    }}
-                }, {
-                /* the single buttons for 10% pan*/
-                    xtype:'button',
-                    iconCls: 'singleuparrow',
-                    id: 'singleuparrow',
-                    //text: 'North',
-                    x: 40,
-                    y: 10,
-                    handler: function(b,e) {
-                        cc = python_varname + '.pan_rel((0.0, -0.1))'
-                        yt_rpc.ExtDirectREPL.execute(
-                        {code:cc, hide:true}, cell_finished); 
-                    }
-                }, {
-                    xtype:'button',
-                    iconCls: 'singlerightarrow',
-                    id: 'singlerightarrow',
-                    //text:'East',
-                    x : 60,
-                    y : 30,
-                    handler: function(b,e) {
-                        yt_rpc.ExtDirectREPL.execute(
-                            {code:python_varname + '.pan_rel((0.1, 0.0))',
-                             hide:true},
-                        cell_finished); 
-                    }
-                }, {
-                    xtype:'button',
-                    iconCls: 'singledownarrow',
-                    id: 'singledownarrow',
-                    //text: 'South',
-                    x: 40,
-                    y: 50,
-                    handler: function(b,e) {
-                        yt_rpc.ExtDirectREPL.execute(
-                            {code:python_varname + '.pan_rel((0.0, 0.1))',
-                             hide:true},
-                        cell_finished); 
-                    }
-                }, {
-                    xtype: 'button',
-                    iconCls: 'singleleftarrow',
-                    id: 'singleleftarrow',
-                    //text: 'West',
-                    x: 20,
-                    y: 30,
-                    handler: function(b,e) {
-                        yt_rpc.ExtDirectREPL.execute(
-                            {code:python_varname + '.pan_rel((-0.1, 0.0))',
-                             hide:true},
-                        cell_finished); 
-                    }
-                }, 
-                /* the double buttons for 50% pan*/
-                {
-                    xtype:'button',
-                    iconCls: 'doubleuparrow',
-                    id:'doubleuparrow',
-                    //text: 'North',
-                    x: 40,
-                    y: 80,
-                    handler: function(b,e) {
-                        cc = python_varname + '.pan_rel((0.0, -0.5))'
-                        yt_rpc.ExtDirectREPL.execute(
-                        {code:cc, hide:true}, cell_finished); 
-                    }
-                }, {
-                    xtype:'button',
-                    iconCls: 'doublerightarrow',
-                    id:'doublerightarrow',
-                    //text:'East',
-                    x : 60,
-                    y : 100,
-                    handler: function(b,e) {
-                        yt_rpc.ExtDirectREPL.execute(
-                            {code:python_varname + '.pan_rel((0.5, 0.0))',
-                             hide:true},
-                        cell_finished); 
-                    }
-                }, {
-                    xtype:'button',
-                    iconCls: 'doubledownarrow',
-                    //text: 'South',
-                    id: 'doubledownarrow',
-                    x: 40,
-                    y: 120,
-                    handler: function(b,e) {
-                        yt_rpc.ExtDirectREPL.execute(
-                            {code:python_varname + '.pan_rel((0.0, 0.5))',
-                             hide:true},
-                        cell_finished); 
-                    }
-                }, {
-                    xtype: 'button',
-                    iconCls: 'doubleleftarrow',
-                    id: 'doubleleftarrow',
-                    //text: 'West',
-                    x: 20,
-                    y: 100,
-                    handler: function(b,e) {
-                        yt_rpc.ExtDirectREPL.execute(
-                            {code:python_varname + '.pan_rel((-0.5, 0.0))',
-                             hide:true},
-                        cell_finished); 
-                    }
-                },
-                /* Now the zoom buttons */
-                {
-                    xtype: 'button',
-                    text: 'Zoom In 10x',
-                    id: "zoom10x",
-                    x: 10,
-                    y: 160,
-                    width: 80,
-                    handler: function(b,e) {
-                        yt_rpc.ExtDirectREPL.execute(
-                            {code:python_varname + '.zoom(10.0)',
-                             hide:true},
-                        cell_finished); 
-                    }
-                },{
-                    xtype: 'button',
-                    text: 'Zoom In 2x',
-                    id: "zoom2x",
-                    x: 10,
-                    y: 185,
-                    width: 80,
-                    handler: function(b,e) {
-                        yt_rpc.ExtDirectREPL.execute(
-                            {code:python_varname + '.zoom(2.0)',
-                             hide:true},
-                        cell_finished); 
-                    }
-                },{
-                    xtype: 'button',
-                    text: 'Zoom Out 2x',
-                    id:'zoomout2x',
-                    x: 10,
-                    y: 210,
-                    width: 80,
-                    handler: function(b,e) {
-                        yt_rpc.ExtDirectREPL.execute(
-                            {code:python_varname + '.zoom(0.5)',
-                             hide:true},
-                        cell_finished); 
-                    }
-                },{
-                    xtype: 'button',
-                    text: 'Zoom Out 10x',
-                    id:'zoomout10x',
-                    x: 10,
-                    y: 235,
-                    width: 80,
-                    handler: function(b,e) {
-                        yt_rpc.ExtDirectREPL.execute(
-                            {code:python_varname + '.zoom(0.1)',
-                             hide:true},
-                        cell_finished); 
-                    }
-                },{
-                    xtype: 'button',
-                    text: 'Upload Image',
-                    x: 10,
-                    y: 285,
-                    width: 80,
-                    tooltip: "Upload the current image to " +
-                             "<a href='http://imgur.com'>imgur.com</a>",
-                    handler: function(b,e) {
-                        img_data = image_dom.src;
-                        yt_rpc.ExtDirectREPL.upload_image(
-                            {image_data:img_data,
-                             caption:metadata_string},
-                        function(rv) {
-                            var alert_text;
-                            if(rv['uploaded'] == false) {
-                                alert_text = "Failure uploading image!";
-                            } else {
-                                alert_text = "Uploaded to " +
-                                        rv['upload']['links']['imgur_page'];
-                            }
-                            Ext.Msg.alert('imgur.com', alert_text);
-                            var record = new logging_store.recordType(
-                                {record: alert_text });
-                            logging_store.add(record, number_log_records++);
-                        }); 
-                    }
-                },{
-                    xtype: 'button',
-                    text: 'Pannable Map',
-                    x: 10,
-                    y: 335,
-                    width: 80,
-                    tooltip: "Open a pannable map in a new tab",
-                    handler: function(b,e) {
-                        img_data = image_dom.src;
-                        yt_rpc.ExtDirectREPL.create_mapview(
-                            {widget_name:python_varname},
-                        function(rv) {
-                            /*alert(rv);*/
-                        }); 
-                    }
-                },{
-                    xtype: 'panel',
-                    layout: 'vbox',
-                    id: 'rhs_panel_' + python_varname,
-                    width: 250,
-                    height: 460,
-                    x: 690, y: 10,
-                    layoutConfig: {
-                        align: 'stretch',
-                        pack: 'start',
-                    },
-                    items: [
-                        {
-                          xtype: 'panel',
-                          title: 'Plot MetaData',
-                          id: 'metadata_' + python_varname,
-                          style: {fontFamily: '"Inconsolata", monospace'},
-                          html: 'Welcome to the Plot Window.',
-                          height: 200,
-                        }, {
-                          xtype: 'tabpanel',
-                          id: 'editor_panel',
-                          flex: 1,
-                          activeTab: 0,
-                          items: [
-                        {
-                          xtype: 'panel',
-                          title: 'Plot Editor',
-                          id: 'plot_edit',
-                          style: {fontFamily: '"Inconsolata", monospace'},
-                          layout: 'absolute',
-                          flex: 1,
-                          items : [
-                             {
-                               x: 10,
-                               y: 20,
-                               width: 70,
-                               xtype: 'label',
-                               text: 'Display',
-                             },
-                             {
-                               x: 80,
-                               y: 20,
-                               width : 80,
-                               xtype: 'combo',
-                               editable: false,
-                               triggerAction: 'all',
-                               validateOnBlur: false,
-                               store: ['log10', 'linear'],
-                               value: widget_data['initial_transform'],
-                               listeners: {select: function(combo, record, index){ 
-                                   var newValue = '"' + record.data['field1'] + '"';
-                                   yt_rpc.ExtDirectREPL.execute(
-                                       {code:python_varname + '.set_transform('
-                                         + python_varname + '._current_field, '
-                                         + newValue + ')', hide:false},
-                                         cell_finished);
-                               }}
-                             },
-                             {
-                               x: 10,
-                               y: 60,
-                               width: 70,
-                               xtype: 'label',
-                               text: 'Colormap',
-                             },
-                             {
-                               x: 80,
-                               y: 60,
-                               width : 140,
-                               xtype: 'combo',
-                               editable: false,
-                               triggerAction: 'all',
-                               validateOnBlur: false,
-                               store: ['algae', 'RdBu', 'gist_stern',  
-                                       'hot', 'jet', 'kamae', 
-                                        'B-W LINEAR', 'BLUE',
-                                        'GRN-RED-BLU-WHT', 'RED TEMPERATURE',
-                                        'BLUE', 'STD GAMMA-II', 'PRISM',
-                                        'RED-PURPLE', 'GREEN', 'GRN',
-                                        'GREEN-PINK', 'BLUE-RED', '16 LEVEL',
-                                        'RAINBOW', 'STEPS', 'STERN SPECIAL',
-                                        'Haze', 'Blue - Pastel - Red',
-                                        'Pastels', 'Hue Sat Lightness 1',
-                                        'Hue Sat Lightness 2', 'Hue Sat Value 1',
-                                        'Hue Sat Value 2', 'Purple-Red + Stripes',
-                                        'Beach', 'Mac Style', 'Eos A', 'Eos B',
-                                        'Hardcandy', 'Nature', 'Ocean', 'Peppermint',
-                                        'Plasma', 'Blue-Red', 'Rainbow', 'Blue Waves',
-                                        'Volcano', 'Waves', 'Rainbow18',
-                                        'Rainbow + white', 'Rainbow + black'],
-                               value: 'algae',
-                               listeners: {select: function(combo, record, index){ 
-                                   var newValue = '"' + record.data['field1'] + '"';
-                                   yt_rpc.ExtDirectREPL.execute(
-                                       {code:python_varname + '.set_cmap('
-                                         + python_varname + '._current_field, '
-                                         + newValue + ')', hide:false},
-                                         cell_finished);
-                               }}
-                             }
-                          ]
-                        }, {
-                          xtype: 'panel',
-                          title: 'Contours',
-                          id: 'contour_edit',
-                          style: {fontFamily: '"Inconsolata", monospace'},
-                          layout: 'absolute',
-                          flex: 1,
-                          items : [
-                             {
-                               x: 10,
-                               y: 20,
-                               width: 70,
-                               xtype: 'label',
-                               text: 'Field',
-                             }, {
-                               x: 80,
-                               y: 20,
-                               width : 160,
-                               xtype: 'combo',
-                               editable: false,
-                               id: 'field',
-                               triggerAction: 'all',
-                               validateOnBlur: false,
-                               value:widget_data['initial_field'],
-                               store: widget_data['fields'],
-                             }, {
-                               x: 10,
-                               y: 60,
-                               width: 70,
-                               xtype: 'label',
-                               text: 'Levels',
-                             }, {
-                               x: 80,
-                               y: 60,
-                               width : 160,
-                               xtype: 'slider',
-                               id: 'ncont',
-                               minValue: 0,
-                               maxValue: 10,
-                               value: 5,
-                               increment: 1,
-                               plugins: new Ext.slider.Tip(),
-                             }, {
-                               x: 10,
-                               y: 100,
-                               width: 70,
-                               xtype: 'label',
-                               text: 'Logspaced',
-                             }, {
-                               x: 80,
-                               y: 100,
-                               width : 160,
-                               xtype: 'checkbox',
-                               id: 'logit',
-                               checked: true,
-                             }, {
-                               x: 10,
-                               y: 180,
-                               width: 80,
-                               xtype: 'button',
-                               text: 'Apply',
-                               handler: function(b, e) {
-                                  field = contour_window.get('field').getValue();
-                                  ncont = contour_window.get('ncont').getValue();
-                                  logit = contour_window.get('logit').getValue();
-                                  if (logit == false) logit = 'False';
-                                  else if (logit == true) logit = 'True';
-                                  yt_rpc.ExtDirectREPL.execute(
-                                      {code:python_varname
-                                       + '.set_contour_info("' + field + '", '
-                                       + ncont + ', ' + logit + ')',
-                                        hide:false},
-                                      cell_finished);
-                               }
-                             }
-                          ]
-                        }, {
-                          xtype: 'panel',
-                          title: 'Velocity Vectors',
-                          id: 'vector_edit',
-                          style: {fontFamily: '"Inconsolata", monospace'},
-                          layout: 'absolute',
-                          flex: 1,
-                          items : [
-                             {
-                               x: 10,
-                               y: 60,
-                               width: 70,
-                               xtype: 'label',
-                               text: 'Skip Factor',
-                             }, {
-                               x: 80,
-                               y: 60,
-                               width : 160,
-                               xtype: 'slider',
-                               id: 'skip',
-                               minValue: 1,
-                               maxValue: 64,
-                               value: 32,
-                               increment: 1,
-                               plugins: new Ext.slider.Tip(),
-                             }, {
-                               x: 10,
-                               y: 180,
-                               width: 80,
-                               xtype: 'button',
-                               text: 'Apply',
-                               handler: function(b, e) {
-                                  skip = vector_window.get('skip').getValue();
-                                  yt_rpc.ExtDirectREPL.execute(
-                                      {code:python_varname
-                                       + '.set_vector_info('+skip+')',
-                                        hide:false},
-                                      cell_finished);
-                               }
-                             }
-                          ]
-                        }
-                        ] } /* tabpanel items and entry */
-                        ]
-                }
-            ]
-        }
-    );
-
-    viewport.get("center-panel").activate("pw_" + this.id);
-    viewport.get("center-panel").doLayout();
-    viewport.doLayout();
-    this.panel = viewport.get("center-panel").get("pw_" + python_varname);
-    this.panel.doLayout();
-    this.panel.show();
-    this.image_panel = this.panel.get("image_panel_"+python_varname);
-    this.ticks = this.panel.get("ticks_"+python_varname);
-    var ticks = this.ticks;
-    var colorbar = this.panel.get("colorbar_"+python_varname);
-    this.metadata_panel = this.panel.get("rhs_panel_" + python_varname).get("metadata_" + python_varname);
-    this.zoom_scroll = this.panel.get("slider_" + python_varname);
-    var contour_window = this.panel.get("rhs_panel_" + python_varname);
-    contour_window = contour_window.get("editor_panel");
-    contour_window = contour_window.get("contour_edit");
-    var vector_window = this.panel.get("rhs_panel_" + python_varname);
-    vector_window = vector_window.get("editor_panel");
-    vector_window = vector_window.get("vector_edit");
-    var image_dom = this.image_panel.el.dom;
-    var control_panel = this.panel;
-    var metadata_string;
-
-    this.accept_results = function(payload) {
-        this.image_panel.el.dom.src = "data:image/png;base64," + payload['image_data'];
-        this.zoom_scroll.setValue(0, payload['zoom'], true);
-        this.metadata_panel.update(payload['metadata_string']);
-        metadata_string = payload['metadata_string'];
-        ticks.removeAll();
-        Ext.each(payload['ticks'], function(tick, index) {
-            ticks.add({xtype:'panel',
-                       width: 10, height:1,
-                       style: 'background-color: #000000;',
-                       html:' ',
-                       x:0, y: 10 + tick[0]});
-            ticks.add({xtype:'panel',
-                       width: 90, height:15,
-                       border: false,
-                       style: 'font-family: "Inconsolata", monospace;' +
-                              'font-size: 12px;',
-                       html: '' + tick[2] + '',
-                       x:12, y: 4 + tick[0]});
-        });
-        if (payload['colorbar_image'] != null) {
-            colorbar.el.dom.src = "data:image/png;base64," +
-                payload['colorbar_image'];
-        }
-        ticks.doLayout();
-    }
-
-    yt_rpc.ExtDirectREPL.execute(
-        {code:python_varname + '.zoom(1.0)', hide:true},
-        CELl_finished);
-    },
-
     statics: {
         widgetName: 'plotwindow',
         supportsDataObjects: false,
         supportsParameterFiles: true,
         displayName: 'Do not use',
         preCreation: function(obj) {
+            examine = this;
             var widget = Ext.create(this.getName())
             var ts = widget.templateManager.applyObject(obj);
-            var win;
             function makeProj(b, e) {
                 var axis = Ext.get("axis").getValue();
                 var field = Ext.get("field").getValue();
@@ -783,65 +140,15 @@
                       Ext.emptyFn);
                 Ext.WindowManager.getActive().close();
             }
-            win = new Ext.Window({
-                layout: 'fit',
-                width: 370,
-                height: 220,
-                modal: true,
-                resizable: false,
-                draggable: false,
-                border: false,
-                title: ts.pwt,
-                items: [{
-                    xtype: 'form',
-                    labelWidth:80,
-                    frame:true,
-                    items: [{
-                        xtype:'combo',
-                        fieldLabel: 'Axis',
-                        id: 'axis',
-                        store:['X','Y','Z'],
-                        width: 230,
-                        allowBlank:false,
-                        triggerAction: 'all',
-                        value: 'X',
-                    },{
-                        xtype:'checkbox',
-                        fieldLabel: 'Center on Max',
-                        id: 'max_dens',
-                        width: 90,
-                        allowBlank:false,
-                    },{
-                        xtype:'combo',
-                        fieldLabel: 'Field',
-                        id: 'field',
-                        store:obj.field_list,
-                        width: 230,
-                        allowBlank:false,
-                        triggerAction: 'all',
-                        value: 'Density'
-                    },{
-                        xtype:'combo',
-                        fieldLabel: 'Weight Field',
-                        id: 'weightField',
-                        store:['None'].concat(obj.field_list),
-                        width: 230,
-                        allowBlank:false,
-                        triggerAction: 'all',
-                        value: 'None'
-                    }],
-                    buttons: [
-                        {
-                            text: 'Project',
-                            listeners: widget.prepHandler(makeProj),
-                        },{
-                            text: 'Cancel',
-                            handler: function(){win.close();},
-                        }
-                    ]
-                }]
-            });
-            win.show();
-        },
+            win = Ext.widget("plotwindowcreator", {title:ts.pwt, obj:obj});
+            win.query("#weightField")[0].store = 
+                ['None'].concat(obj.field_list);
+            win.query("#field")[0].store = obj.field_list;
+            /*win.show();*/
+            var ww = Ext.widget("plotwindow");
+            examine = ww;
+            widget.applyExecuteHandlers(ww);
+            Ext.ComponentQuery.query("viewport > #center-panel")[0].add(ww);
+        }
     },
 });


diff -r 1d175c79750299573316b33dbf34864b2f40795b -r 7e8979ad9a7aeb980243b9b885febdb559a64fd5 yt/gui/reason/html/app/templates/TemplateContainer.js
--- a/yt/gui/reason/html/app/templates/TemplateContainer.js
+++ b/yt/gui/reason/html/app/templates/TemplateContainer.js
@@ -44,7 +44,6 @@
         var tpl;
         Ext.iterate(this.getTemplates(), function(k, v, o){
             tpl = new Ext.XTemplate(v);
-            examine = {tpl: tpl, v:v, k:k};
             applied[k] = tpl.apply(obj);
         });
         return applied;


diff -r 1d175c79750299573316b33dbf34864b2f40795b -r 7e8979ad9a7aeb980243b9b885febdb559a64fd5 yt/gui/reason/html/app/view/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/view/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/view/widgets/PlotWindow.js
@@ -39,6 +39,23 @@
     width: '100%',
     height: '100%',
     closable: true,
+    refs: [
+        { ref: 'field',
+          selector: '#field'
+        }, {
+          ref: 'ncont',
+          selector: '#ncont',
+        }, {
+          ref: 'logit',
+          selector: '#logit'
+        }, {
+          ref: 'vectorSkip',
+          selector: '#skip'
+        }, {
+          ref: 'contourField',
+          selector: '#contourfield',
+        },
+    ],
 
     items: [ 
         { xtype:'image',
@@ -57,8 +74,8 @@
             style: 'border: 1px solid #000000;',
             x: 510,
             y: 10,
-            width: 28,
-            height: 398,
+            width: 30,
+            height: 400,
         }, {
             xtype: 'panel',
             id: 'ticks',
@@ -79,6 +96,7 @@
         },{
             xtype: 'combo',
             text: 'Field',
+            id: 'fieldSelector',
             x: 100,
             y: 435,
             width: 400,
@@ -151,14 +169,14 @@
         {
             xtype: 'button',
             text: 'Zoom In 10x',
-            id: "zoom10x",
+            id: "zoomin10x",
             x: 10,
             y: 160,
             width: 80,
         },{
             xtype: 'button',
             text: 'Zoom In 2x',
-            id: "zoom2x",
+            id: "zoomin2x",
             x: 10,
             y: 185,
             width: 80,
@@ -179,6 +197,7 @@
         },{
             xtype: 'button',
             text: 'Upload Image',
+            id: 'uploadimage',
             x: 10,
             y: 285,
             width: 80,
@@ -187,6 +206,7 @@
         },{
             xtype: 'button',
             text: 'Pannable Map',
+            id: 'pannablemap',
             x: 10,
             y: 335,
             width: 80,
@@ -236,6 +256,7 @@
                        y: 20,
                        width : 80,
                        xtype: 'combo',
+                       id: 'transform',
                        editable: false,
                        triggerAction: 'all',
                        validateOnBlur: false,
@@ -254,6 +275,7 @@
                        y: 60,
                        width : 140,
                        xtype: 'combo',
+                       id: 'colormap',
                        editable: false,
                        triggerAction: 'all',
                        validateOnBlur: false,
@@ -297,7 +319,7 @@
                        width : 160,
                        xtype: 'combo',
                        editable: false,
-                       id: 'field',
+                       id: 'contourfield',
                        triggerAction: 'all',
                        validateOnBlur: false,
                        value: '',
@@ -337,6 +359,7 @@
                        y: 180,
                        width: 80,
                        xtype: 'button',
+                       id: 'contourapply',
                        text: 'Apply',
                      }
                   ]
@@ -370,6 +393,7 @@
                        y: 180,
                        width: 80,
                        xtype: 'button',
+                       id: 'vectorsapply',
                        text: 'Apply',
                      }
                   ]



https://bitbucket.org/yt_analysis/yt/changeset/bb87e930b036/
changeset:   bb87e930b036
branch:      yt
user:        MatthewTurk
date:        2012-06-01 06:30:55
summary:     Create projections and execute the code server side.
affected #:  3 files

diff -r 7e8979ad9a7aeb980243b9b885febdb559a64fd5 -r bb87e930b03679e915f57ff2df5b01efb705cce0 yt/gui/reason/html/app/controller/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
@@ -128,27 +128,30 @@
             var widget = Ext.create(this.getName())
             var ts = widget.templateManager.applyObject(obj);
             function makeProj(b, e) {
-                var axis = Ext.get("axis").getValue();
-                var field = Ext.get("field").getValue();
-                var weight = Ext.get("weightField").getValue();
-                var onmax = Ext.get("max_dens").getValue();
                 reason.fireEvent("disableinput");
+                examine = win;
                 yt_rpc.ExtDirectREPL.create_proj({
                         pfname: obj.varname,
-                        axis: axis, field: field, weight: weight,
-                        onmax: onmax},
-                      Ext.emptyFn);
-                Ext.WindowManager.getActive().close();
+                        axis: win.query("#axis")[0].getValue(),
+                        field: win.query("#field")[0].getValue(),
+                        weight: win.query("#weightField")[0].getValue(),
+                        onmax: win.query("#maxDens")[0].getValue(),
+                }, function() { examine = arguments; });
+                win.destroy();
             }
             win = Ext.widget("plotwindowcreator", {title:ts.pwt, obj:obj});
             win.query("#weightField")[0].store = 
                 ['None'].concat(obj.field_list);
             win.query("#field")[0].store = obj.field_list;
-            /*win.show();*/
+            win.query("#create")[0].on('click', makeProj);
+            win.query("#cancel")[0].on('click', function(){win.destroy;});
+            win.show();
+            /*
             var ww = Ext.widget("plotwindow");
             examine = ww;
             widget.applyExecuteHandlers(ww);
             Ext.ComponentQuery.query("viewport > #center-panel")[0].add(ww);
+            */
         }
     },
 });


diff -r 7e8979ad9a7aeb980243b9b885febdb559a64fd5 -r bb87e930b03679e915f57ff2df5b01efb705cce0 yt/gui/reason/html/app/view/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/view/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/view/widgets/PlotWindow.js
@@ -40,21 +40,11 @@
     height: '100%',
     closable: true,
     refs: [
-        { ref: 'field',
-          selector: '#field'
-        }, {
-          ref: 'ncont',
-          selector: '#ncont',
-        }, {
-          ref: 'logit',
-          selector: '#logit'
-        }, {
-          ref: 'vectorSkip',
-          selector: '#skip'
-        }, {
-          ref: 'contourField',
-          selector: '#contourfield',
-        },
+        { ref: 'field', selector: '#field' },
+        { ref: 'ncont', selector: '#ncont' },
+        { ref: 'logit', selector: '#logit' },
+        { ref: 'vectorSkip', selector: '#skip' },
+        { ref: 'contourField', selector: '#contourfield' },
     ],
 
     items: [ 


diff -r 7e8979ad9a7aeb980243b9b885febdb559a64fd5 -r bb87e930b03679e915f57ff2df5b01efb705cce0 yt/gui/reason/html/app/view/widgets/PlotWindowCreator.js
--- a/yt/gui/reason/html/app/view/widgets/PlotWindowCreator.js
+++ b/yt/gui/reason/html/app/view/widgets/PlotWindowCreator.js
@@ -40,7 +40,7 @@
     draggable: false,
     border: false,
     title: "You shouldn't see this.",
-    
+
     items: [{ xtype: 'form',
               labelWidth:80,
               frame:true,
@@ -56,7 +56,7 @@
               },{
                   xtype:'checkbox',
                   fieldLabel: 'Center on Max',
-                  id: 'max_dens',
+                  id: 'maxDens',
                   width: 90,
                   allowBlank:false,
               },{



https://bitbucket.org/yt_analysis/yt/changeset/ebcea387439a/
changeset:   ebcea387439a
branch:      yt
user:        MatthewTurk
date:        2012-06-01 14:47:48
summary:     Set our data objects to only update every 5 seconds.  (Better logic is needed
for this, on the server side.)  Add payload handling for plot windows.  Add
creation of plot window displays.  Add a bunch of refs for plot windows.
affected #:  6 files

diff -r bb87e930b03679e915f57ff2df5b01efb705cce0 -r ebcea387439a5793d04595849302a0b1e996574a yt/gui/reason/html/app/controller/Notebook.js
--- a/yt/gui/reason/html/app/controller/Notebook.js
+++ b/yt/gui/reason/html/app/controller/Notebook.js
@@ -108,11 +108,6 @@
         this.getInputLine().setReadOnly(false);
         console.log("Calling FileList");
         var application = this.application;
-        yt_rpc.ExtDirectParameterFileList.get_list_of_pfs({}, 
-            function(f, a) {
-                if (f == null) { alert("Error!"); return; }
-                application.fireEvent("newdataobjects", f);
-        });
     },
 
     cellExecuted: function(result) {


diff -r bb87e930b03679e915f57ff2df5b01efb705cce0 -r ebcea387439a5793d04595849302a0b1e996574a yt/gui/reason/html/app/controller/PayloadDirector.js
--- a/yt/gui/reason/html/app/controller/PayloadDirector.js
+++ b/yt/gui/reason/html/app/controller/PayloadDirector.js
@@ -45,11 +45,23 @@
         this.heartbeat = this.taskRunner.start(
             {run: this.heartbeatCall,
              interval: 250});
+        this.heartbeat = this.taskRunner.start(
+            {run: this.dataObjectsCall,
+             interval: 5000});
         this.callParent(arguments);
     },
     handlePayload: function(payload) {
         this.application.fireEvent('payload' + payload['type'], payload);
     },
+
+    dataObjectsCall: function() {
+        yt_rpc.ExtDirectParameterFileList.get_list_of_pfs({}, 
+            function(f, a) {
+                if (f == null) { alert("Error!"); return; }
+                reason.fireEvent("newdataobjects", f);
+        });
+    },
+
     heartbeatCall: function() {
         if (heartbeatRequest == true) return;
         heartbeatRequest = true;


diff -r bb87e930b03679e915f57ff2df5b01efb705cce0 -r ebcea387439a5793d04595849302a0b1e996574a yt/gui/reason/html/app/controller/WidgetDirector.js
--- a/yt/gui/reason/html/app/controller/WidgetDirector.js
+++ b/yt/gui/reason/html/app/controller/WidgetDirector.js
@@ -38,6 +38,8 @@
         this.application.addListener({
             createwidget: {fn: this.createWidget, scope: this},
             showwidgets: {fn: this.showWidgetMenu, scope: this},
+            payloadwidget: {fn: this.newWidgetCreated, scope: this},
+            payloadwidget_payload: {fn: this.sendPayload, scope: this},
         });
         this.callParent(arguments);
     },
@@ -57,7 +59,6 @@
     createWidget: function(b, e) {
         var w = b.widget;
         console.log("Asked to create " + b.widget.widgetName);
-        var store = this.getWidgetInstancesStore();
         b.widget.preCreation(b.dataObj);
     },
 
@@ -87,4 +88,44 @@
         contextMenu.showAt(e.getXY());
     },
 
+    newWidgetCreated: function(payload) {
+        /* We have the following fields:
+                type             ('widget')
+                widget_type
+                varname
+                data             (has subfields)
+
+           We now obtain our class, create that with the factory, and we add
+           the resultant class to our store.
+        */
+        var resultId = this.getWidgetTypesStore().find(
+            'widgetname', payload['widget_type']);
+        if (resultId == -1) {
+            Ext.Error.raise('Did not recognize widget type "' +
+                            payload['widget_type'] + '".');
+        }
+        var widgetInfo = this.getWidgetTypesStore().getAt(resultId).data;
+        /* The widget adds its view to the viewport. */
+        var newWidget = Ext.create(widgetInfo['widgetclass'].getName(),
+                            {payload: payload});
+        this.getWidgetInstancesStore().add({
+            widgetid: payload['varname'],
+            widgettype: widgetInfo.widgetname,
+            widget: newWidget
+        });
+        newWidget.createView();
+    },
+
+    sendPayload: function(payload) {
+        var resultId = this.getWidgetInstancesStore().find(
+            'widgetid', payload['widget_id']);
+        examine = payload;
+        if (resultId == -1) {
+            Ext.Error.raise('Could not find widget "' +
+                            payload['widget_id'] + '".');
+        }
+        var widgetInfo = this.getWidgetInstancesStore().getAt(resultId).data;
+        widgetInfo['widget'].applyPayload(payload);
+    },
+
 });


diff -r bb87e930b03679e915f57ff2df5b01efb705cce0 -r ebcea387439a5793d04595849302a0b1e996574a yt/gui/reason/html/app/controller/widgets/BaseWidget.js
--- a/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
+++ b/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
@@ -66,6 +66,7 @@
             ww.query(id)[0].on(conf);
         };
         Ext.each(this.executionTriggers, function(trigger) {
+            /*console.log(trigger[0] + " " + trigger[1] + " " + trigger[2]);*/
             ef.call(this, trigger[0], trigger[1], trigger[2]);
         }, this);
     },


diff -r bb87e930b03679e915f57ff2df5b01efb705cce0 -r ebcea387439a5793d04595849302a0b1e996574a yt/gui/reason/html/app/controller/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
@@ -71,7 +71,7 @@
     ],
 
     executionTriggers: [
-        ['#slider', 'changecomplete', 'scrollZoom'],
+        ['#zoomSlider', 'changecomplete', 'scrollZoom'],
         ['#fieldSelector', 'select', 'fieldChange'],
         ['#singleuparrow', 'click', 'singleUpArrow'],
         ['#singlerightarrow', 'click', 'singleRightArrow'],
@@ -91,11 +91,24 @@
         ['#vectorsapply', 'click', 'adjustVectors'],
     ],
 
-    applyPayload: function(payload, instance) {
-        this.image_panel.el.dom.src = "data:image/png;base64," + payload['image_data'];
-        this.zoom_scroll.setValue(0, payload['zoom'], true);
-        this.metadata_panel.update(payload['metadata_string']);
-        metadata_string = payload['metadata_string'];
+    refs: [
+        { ref: 'colorbar', selector: '#colorbar'},
+        { ref: 'image', selector: '#image_panel'},
+        { ref: 'fieldSelector', selector: '#fieldSelector'},
+        { ref: 'transform', selector: '#transform'},
+        { ref: 'contourField', selector: '#contourfield'},
+        { ref: 'zoomSlider', selector: '#zoomSlider'},
+        { ref: 'metadataString', selector: '#metadataString'},
+        { ref: 'ticks', selector: '#ticks'},
+    ],
+
+    applyPayload: function(payload) {
+        examine = {tt:this, pp:payload};
+        this.getImage().getEl("img").dom.src = 
+            "data:image/png;base64," + payload['image_data'];
+        this.getZoomSlider().setValue(0, payload['zoom'], true);
+        this.getMetadataString().update(payload['metadata_string']);
+        var ticks = this.getTicks();
         ticks.removeAll();
         Ext.each(payload['ticks'], function(tick, index) {
             ticks.add({xtype:'panel',
@@ -112,14 +125,31 @@
                        x:12, y: 4 + tick[0]});
         });
         if (payload['colorbar_image'] != null) {
-            colorbar.el.dom.src = "data:image/png;base64," +
-                payload['colorbar_image'];
+            this.getColorbar().getEl("img").dom.src =
+                "data:image/png;base64," + payload['colorbar_image'];
         }
         ticks.doLayout();
     },
 
+    createView: function() {
+        var wd = this.payload['data'];
+        this.plotWindowView = Ext.widget("plotwindow",{
+            varname : this.payload['varname'],
+            title: wd['title'],
+        });
+        this.getColorbar().src = "data:image/png;base64," + wd['colorbar'];
+        this.getFieldSelector().store = wd['fields'];
+        this.getFieldSelector().value = wd['initial_field'];
+        this.getTransform().value = wd['initial_transform'];
+        this.getContourField().store = wd['fields'];
+        this.getContourField().value = wd['initial_field'];
+        this.applyExecuteHandlers(this.plotWindowView);
+        Ext.ComponentQuery.query("viewport > #center-panel")[0].add(
+            this.plotWindowView);
+    },
+
     statics: {
-        widgetName: 'plotwindow',
+        widgetName: 'plot_window',
         supportsDataObjects: false,
         supportsParameterFiles: true,
         displayName: 'Do not use',
@@ -129,7 +159,6 @@
             var ts = widget.templateManager.applyObject(obj);
             function makeProj(b, e) {
                 reason.fireEvent("disableinput");
-                examine = win;
                 yt_rpc.ExtDirectREPL.create_proj({
                         pfname: obj.varname,
                         axis: win.query("#axis")[0].getValue(),
@@ -146,12 +175,10 @@
             win.query("#create")[0].on('click', makeProj);
             win.query("#cancel")[0].on('click', function(){win.destroy;});
             win.show();
-            /*
-            var ww = Ext.widget("plotwindow");
-            examine = ww;
-            widget.applyExecuteHandlers(ww);
-            Ext.ComponentQuery.query("viewport > #center-panel")[0].add(ww);
-            */
-        }
+            /* Note that in this case, our instance of 'widget', which is this
+               class, is not long-lived.  It dies after the window is
+               destroyed. */
+        },
+
     },
 });


diff -r bb87e930b03679e915f57ff2df5b01efb705cce0 -r ebcea387439a5793d04595849302a0b1e996574a yt/gui/reason/html/app/view/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/view/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/view/widgets/PlotWindow.js
@@ -39,13 +39,6 @@
     width: '100%',
     height: '100%',
     closable: true,
-    refs: [
-        { ref: 'field', selector: '#field' },
-        { ref: 'ncont', selector: '#ncont' },
-        { ref: 'logit', selector: '#logit' },
-        { ref: 'vectorSkip', selector: '#skip' },
-        { ref: 'contourField', selector: '#contourfield' },
-    ],
 
     items: [ 
         { xtype:'image',
@@ -77,7 +70,7 @@
             items : [],
             border: false,
         }, {   xtype: 'multislider',
-            id: 'slider',
+            id: 'zoomSlider',
             minValue: 0,
             maxValue: 100,
             increment: 0.1,
@@ -216,7 +209,7 @@
                 {
                   xtype: 'panel',
                   title: 'Plot MetaData',
-                  id: 'metadata',
+                  id: 'metadataString',
                   style: {fontFamily: '"Inconsolata", monospace'},
                   html: 'Welcome to the Plot Window.',
                   height: 200,



https://bitbucket.org/yt_analysis/yt/changeset/d0b7dcbaff63/
changeset:   d0b7dcbaff63
branch:      yt
user:        MatthewTurk
date:        2012-06-01 22:56:04
summary:     Progress bar now works.
affected #:  2 files

diff -r ebcea387439a5793d04595849302a0b1e996574a -r d0b7dcbaff63ddad4291b16574f0a75632ed984c yt/gui/reason/html/app/controller/WidgetDirector.js
--- a/yt/gui/reason/html/app/controller/WidgetDirector.js
+++ b/yt/gui/reason/html/app/controller/WidgetDirector.js
@@ -27,6 +27,7 @@
     extend: 'Ext.app.Controller',
     requires: ["Reason.controller.widgets.SampleWidget",
                "Reason.controller.widgets.PlotWindow",
+               "Reason.controller.widgets.ProgressBar",
     ],
     stores: ['WidgetTypes', 'WidgetInstances'],
 


diff -r ebcea387439a5793d04595849302a0b1e996574a -r d0b7dcbaff63ddad4291b16574f0a75632ed984c yt/gui/reason/html/app/controller/widgets/ProgressBar.js
--- a/yt/gui/reason/html/app/controller/widgets/ProgressBar.js
+++ b/yt/gui/reason/html/app/controller/widgets/ProgressBar.js
@@ -23,29 +23,39 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ***********************************************************************/
 
+Ext.define("Reason.controller.widgets.ProgressBar", {
+    extend: 'Reason.controller.widgets.BaseWidget',
+    requires: [],
 
+    templates: {
 
-var WidgetProgressBar = function(python_varname, widget_data) {
-    this.id = 'pbar_top';
+    },
 
-    Ext.MessageBox.show({
-        title: 'yt is working ...',
-        msg: widget_data.title,
-        progressText: 'Progress',
-        width: 300,
-        progress: true,
-        closable: false,
-    });
+    createView: function() {
+        Ext.MessageBox.show({
+            title: 'yt is working ...',
+            msg: this.payload['data'].title,
+            progressText: 'Progress',
+            width: 300,
+            progress: true,
+            closable: false,
+        });
+    },
 
-    this.accept_results = function(payload) {
+    applyPayload: function(payload) {
         var i = payload['value'];
         if (i == -1) {
             Ext.MessageBox.hide();
         } else {
             Ext.MessageBox.updateProgress(i, Math.round(100*i)+'% completed');
         }
-    }
+    },
 
-}
+    statics: {
+        widgetName: "progressbar",
+        supportsDataObjects: false,
+        supportsParameterFiles: false,
+        displayName: 'Do not use',
+    },
 
-widget_types['progressbar'] = WidgetProgressBar;
+});



https://bitbucket.org/yt_analysis/yt/changeset/f691807d69d9/
changeset:   f691807d69d9
branch:      yt
user:        MatthewTurk
date:        2012-06-01 23:50:02
summary:     Ensuring the progress bar widget has the correct (singleton) id
affected #:  1 file

diff -r d0b7dcbaff63ddad4291b16574f0a75632ed984c -r f691807d69d9cd0b9cc353d3a4e33f2916eda965 yt/gui/reason/extdirect_repl.py
--- a/yt/gui/reason/extdirect_repl.py
+++ b/yt/gui/reason/extdirect_repl.py
@@ -822,7 +822,7 @@
         self.payload_handler.add_payload(
             {'type': 'widget',
              'widget_type': 'progressbar',
-             'varname': None,
+             'varname': 'pbar_top',
              'data': {'title':title}
             })
 



https://bitbucket.org/yt_analysis/yt/changeset/e1bcfa49e217/
changeset:   e1bcfa49e217
branch:      yt
user:        MatthewTurk
date:        2012-06-02 03:44:34
summary:     Adding widget debug panels
affected #:  1 file

diff -r f691807d69d9cd0b9cc353d3a4e33f2916eda965 -r e1bcfa49e2178f174dde79afb94fe0d20d2235e7 yt/gui/reason/html/app/controller/WidgetDirector.js
--- a/yt/gui/reason/html/app/controller/WidgetDirector.js
+++ b/yt/gui/reason/html/app/controller/WidgetDirector.js
@@ -30,6 +30,7 @@
                "Reason.controller.widgets.ProgressBar",
     ],
     stores: ['WidgetTypes', 'WidgetInstances'],
+    views: ['WidgetTypesGrid', 'WidgetInstancesGrid'],
 
     init: function() {
         Ext.iterate(Reason.controller.widgets, function(i, w, ws) {
@@ -41,6 +42,7 @@
             showwidgets: {fn: this.showWidgetMenu, scope: this},
             payloadwidget: {fn: this.newWidgetCreated, scope: this},
             payloadwidget_payload: {fn: this.sendPayload, scope: this},
+            enabledebug: {fn: this.enableDebug, scope: this},
         });
         this.callParent(arguments);
     },
@@ -129,4 +131,13 @@
         widgetInfo['widget'].applyPayload(payload);
     },
 
+    enableDebug: function() {
+        this.instanceView = Ext.widget('widgetinstancesgrid');
+        this.typeView = Ext.widget('widgettypesgrid');
+        Ext.ComponentQuery.query("viewport > #center-panel")[0].add(
+            this.instanceView);
+        Ext.ComponentQuery.query("viewport > #center-panel")[0].add(
+            this.typeView);
+    },
+
 });



https://bitbucket.org/yt_analysis/yt/changeset/84c48a01f994/
changeset:   84c48a01f994
branch:      yt
user:        MatthewTurk
date:        2012-06-02 04:16:17
summary:     Adding more debugging, as well as a few optional stores.  Note that this won't
record widget payloads, even if debug is on, but only the records of what type
of data they sent.
affected #:  9 files

diff -r e1bcfa49e2178f174dde79afb94fe0d20d2235e7 -r 84c48a01f9947dcba9ac536d785c081ec050c01c yt/gui/reason/html/app/controller/DataObjects.js
--- a/yt/gui/reason/html/app/controller/DataObjects.js
+++ b/yt/gui/reason/html/app/controller/DataObjects.js
@@ -58,12 +58,12 @@
     },
 
     refreshDataObjects: function(objs) {
-        console.log("Refreshing data objects");
+        /*console.log("Refreshing data objects");*/
         var root = this.getDataObjectsStore().getRootNode();
         root.removeAll();
         var pf;
         Ext.each(objs, function(o, i, os) {
-            console.log("Appending " + o['name']);
+            /*console.log("Appending " + o['name']);*/
             pf = root.appendChild({
                 name: o.name,
                 type: o.type,
@@ -75,7 +75,7 @@
                 iconCls: 'pf_icon'
             });
             Ext.each(o['children'], function(c, ci, cs) {
-                console.log("    Appending " + c['name']);
+                /*console.log("    Appending " + c['name']);*/
                 pf.appendChild({name: o.name,
                                 type: o.type,
                                 filename: o.filename,


diff -r e1bcfa49e2178f174dde79afb94fe0d20d2235e7 -r 84c48a01f9947dcba9ac536d785c081ec050c01c yt/gui/reason/html/app/controller/MenuActions.js
--- a/yt/gui/reason/html/app/controller/MenuActions.js
+++ b/yt/gui/reason/html/app/controller/MenuActions.js
@@ -42,6 +42,7 @@
             '#pastebinscript': { click: this.pastebinScript },
             '#ytchat': {click: this.openIRCChannel },
             '#quit': {click: this.quitReason },
+            '#enabledebug': {click: this.enableDebug },
         });
         this.callParent(arguments);
     },
@@ -103,5 +104,9 @@
         Ext.Msg.alert("Goodbye!", "Goodbye from Reason!", function() {
         window.open("http://www.google.com/", "_top");});});
     },
+
+    enableDebug: function() {
+        this.application.fireEvent("enabledebug");
+    },
 });
 


diff -r e1bcfa49e2178f174dde79afb94fe0d20d2235e7 -r 84c48a01f9947dcba9ac536d785c081ec050c01c yt/gui/reason/html/app/controller/PayloadDirector.js
--- a/yt/gui/reason/html/app/controller/PayloadDirector.js
+++ b/yt/gui/reason/html/app/controller/PayloadDirector.js
@@ -33,11 +33,14 @@
 
 Ext.define('Reason.controller.PayloadDirector', {
     extend: 'Ext.app.Controller',
+    stores: ['Payloads'],
+    views: ['PayloadGrid'],
 
     init: function() {
         this.application.addListener({
             payloadreceived: {fn: this.handlePayload, scope: this},
             stopheartbeat: {fn: this.stopHeartbeat, scope: this},
+            enabledebug: {fn: this.enableDebug, scope: this},
         })
         /* We also use this as our heartbeat */
         this.taskRunner = new Ext.util.TaskRunner();
@@ -51,6 +54,17 @@
         this.callParent(arguments);
     },
     handlePayload: function(payload) {
+        if (this.payloadGrid) {
+            var wv = payload['varname'];
+            if (payload['type'] == 'widget_payload') {
+                wv = payload['widget_id'];
+            }
+            this.getPayloadsStore().add({
+                payloadtype: payload['type'],
+                widgettype: payload['widget_type'],
+                varname: wv,
+            });
+        }
         this.application.fireEvent('payload' + payload['type'], payload);
     },
 
@@ -81,5 +95,11 @@
     stopHeartbeat: function() {
         this.taskRunner.stopAll();
     },
+
+    enableDebug: function() {
+        this.payloadGrid = Ext.widget("payloadgrid");
+        Ext.ComponentQuery.query("viewport > #center-panel")[0].add(
+            this.payloadGrid);
+    }
 });
 


diff -r e1bcfa49e2178f174dde79afb94fe0d20d2235e7 -r 84c48a01f9947dcba9ac536d785c081ec050c01c yt/gui/reason/html/app/controller/WidgetDirector.js
--- a/yt/gui/reason/html/app/controller/WidgetDirector.js
+++ b/yt/gui/reason/html/app/controller/WidgetDirector.js
@@ -111,6 +111,7 @@
         /* The widget adds its view to the viewport. */
         var newWidget = Ext.create(widgetInfo['widgetclass'].getName(),
                             {payload: payload});
+        console.log("Adding widget payload with varname " + payload['varname']);
         this.getWidgetInstancesStore().add({
             widgetid: payload['varname'],
             widgettype: widgetInfo.widgetname,
@@ -132,6 +133,7 @@
     },
 
     enableDebug: function() {
+        if(this.instanceView) {return;}
         this.instanceView = Ext.widget('widgetinstancesgrid');
         this.typeView = Ext.widget('widgettypesgrid');
         Ext.ComponentQuery.query("viewport > #center-panel")[0].add(


diff -r e1bcfa49e2178f174dde79afb94fe0d20d2235e7 -r 84c48a01f9947dcba9ac536d785c081ec050c01c yt/gui/reason/html/app/store/Payloads.js
--- /dev/null
+++ b/yt/gui/reason/html/app/store/Payloads.js
@@ -0,0 +1,37 @@
+/**********************************************************************
+Payload store for Reason
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define('Reason.store.Payloads', {
+    extend: 'Ext.data.Store',
+    id: 'payloads',
+    fields: ['payloadtype', 'widgettype', 'varname'],
+    data: [],
+});


diff -r e1bcfa49e2178f174dde79afb94fe0d20d2235e7 -r 84c48a01f9947dcba9ac536d785c081ec050c01c yt/gui/reason/html/app/view/MainMenu.js
--- a/yt/gui/reason/html/app/view/MainMenu.js
+++ b/yt/gui/reason/html/app/view/MainMenu.js
@@ -47,6 +47,8 @@
                {xtype: 'menuitem', text: 'Pastebin Script',
                 id: 'pastebinscript'},
                {xtype: 'menuseparator'},
+               {xtype: 'menuitem', text: 'Enable Debug', id: 'enabledebug'},
+               {xtype: 'menuseparator'},
                {xtype:'menuitem', text: 'yt Chat', id: 'ytchat'},
                {xtype: 'menuseparator'},
                {xtype:'menuitem', text: 'Quit', id: 'quit'},


diff -r e1bcfa49e2178f174dde79afb94fe0d20d2235e7 -r 84c48a01f9947dcba9ac536d785c081ec050c01c yt/gui/reason/html/app/view/PayloadGrid.js
--- /dev/null
+++ b/yt/gui/reason/html/app/view/PayloadGrid.js
@@ -0,0 +1,42 @@
+/**********************************************************************
+Received Payloads Grid for Reason
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define('Reason.view.PayloadGrid', {
+    extend: 'Ext.grid.Panel',
+    alias: 'widget.payloadgrid',
+    title: 'Received Payloads',
+    store: 'Payloads',
+    columns: [ {header: 'Payload Type', dataIndex:'payloadtype', flex: 1.0},
+               {header: 'Widget Type', dataIndex: 'widgettype', flex: 1.0},
+               {header: 'Widget Varname', dataIndex: 'varname', flex: 3.0},
+    ],
+});
+


diff -r e1bcfa49e2178f174dde79afb94fe0d20d2235e7 -r 84c48a01f9947dcba9ac536d785c081ec050c01c yt/gui/reason/html/app/view/WidgetInstancesGrid.js
--- /dev/null
+++ b/yt/gui/reason/html/app/view/WidgetInstancesGrid.js
@@ -0,0 +1,41 @@
+/**********************************************************************
+Widget Instances Grid for Reason
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define('Reason.view.WidgetInstancesGrid', {
+    extend: 'Ext.grid.Panel',
+    alias: 'widget.widgetinstancesgrid',
+    title: 'Existing Widgets',
+    store: 'WidgetInstances',
+    columns: [ {header: 'Widget Type', dataIndex:'widgettype', flex: 1.0},
+               {header: 'Widget ID', dataIndex: 'widgetid', flex: 3.0},
+    ],
+});
+


diff -r e1bcfa49e2178f174dde79afb94fe0d20d2235e7 -r 84c48a01f9947dcba9ac536d785c081ec050c01c yt/gui/reason/html/app/view/WidgetTypesGrid.js
--- /dev/null
+++ b/yt/gui/reason/html/app/view/WidgetTypesGrid.js
@@ -0,0 +1,43 @@
+/**********************************************************************
+Widget Types Grid for Reason
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define('Reason.view.WidgetTypesGrid', {
+    extend: 'Ext.grid.Panel',
+    alias: 'widget.widgettypesgrid',
+    title: 'Known Widget Types',
+    store: 'WidgetTypes',
+    columns: [ {header: 'Short Name', dataIndex:'widgetname'},
+               {header: 'Display Name', dataIndex: 'displayname'},
+               {header: 'PFs', dataIndex: 'pfs'},
+               {header: 'DOs', dataIndex: 'objs'}
+    ],
+});
+



https://bitbucket.org/yt_analysis/yt/changeset/0878d2f2892b/
changeset:   0878d2f2892b
branch:      yt
user:        MatthewTurk
date:        2012-06-02 19:47:01
summary:     Switching to 'itemId' in the plot window widget, and adding a helper function
for controller/view-specific ref caching.
affected #:  6 files

diff -r 84c48a01f9947dcba9ac536d785c081ec050c01c -r 0878d2f2892b786970bb6ea33e2933bf0704f730 yt/gui/reason/html/app/controller/PayloadDirector.js
--- a/yt/gui/reason/html/app/controller/PayloadDirector.js
+++ b/yt/gui/reason/html/app/controller/PayloadDirector.js
@@ -54,7 +54,7 @@
         this.callParent(arguments);
     },
     handlePayload: function(payload) {
-        if (this.payloadGrid) {
+        if ((this.payloadGrid) && (payload['type'] != 'logentry')) {
             var wv = payload['varname'];
             if (payload['type'] == 'widget_payload') {
                 wv = payload['widget_id'];
@@ -71,7 +71,7 @@
     dataObjectsCall: function() {
         yt_rpc.ExtDirectParameterFileList.get_list_of_pfs({}, 
             function(f, a) {
-                if (f == null) { alert("Error!"); return; }
+                if (f == null) { return; }
                 reason.fireEvent("newdataobjects", f);
         });
     },


diff -r 84c48a01f9947dcba9ac536d785c081ec050c01c -r 0878d2f2892b786970bb6ea33e2933bf0704f730 yt/gui/reason/html/app/controller/WidgetDirector.js
--- a/yt/gui/reason/html/app/controller/WidgetDirector.js
+++ b/yt/gui/reason/html/app/controller/WidgetDirector.js
@@ -128,7 +128,10 @@
             Ext.Error.raise('Could not find widget "' +
                             payload['widget_id'] + '".');
         }
+        console.log("Directing payload for " + payload['widget_id'] +
+                    " to resultId " + resultId);
         var widgetInfo = this.getWidgetInstancesStore().getAt(resultId).data;
+        examine = widgetInfo;
         widgetInfo['widget'].applyPayload(payload);
     },
 


diff -r 84c48a01f9947dcba9ac536d785c081ec050c01c -r 0878d2f2892b786970bb6ea33e2933bf0704f730 yt/gui/reason/html/app/controller/widgets/BaseWidget.js
--- a/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
+++ b/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
@@ -71,4 +71,17 @@
         }, this);
     },
 
+    createMyRefs: function(varname) {
+        var refs = Array(this.viewRefs.length);
+        var tpl = new Ext.XTemplate("#{varname} {selector}");
+        Ext.each(this.viewRefs, function(v, i, a) {
+            refs[i] = {ref: v['ref'],
+                       selector: tpl.apply({varname:varname,
+                                            selector: v['selector']})
+                      };
+        });
+        this.ref(refs);
+        return refs;
+    },
+
 });


diff -r 84c48a01f9947dcba9ac536d785c081ec050c01c -r 0878d2f2892b786970bb6ea33e2933bf0704f730 yt/gui/reason/html/app/controller/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
@@ -91,7 +91,7 @@
         ['#vectorsapply', 'click', 'adjustVectors'],
     ],
 
-    refs: [
+    viewRefs: [
         { ref: 'colorbar', selector: '#colorbar'},
         { ref: 'image', selector: '#image_panel'},
         { ref: 'fieldSelector', selector: '#fieldSelector'},
@@ -103,7 +103,6 @@
     ],
 
     applyPayload: function(payload) {
-        examine = {tt:this, pp:payload};
         this.getImage().getEl("img").dom.src = 
             "data:image/png;base64," + payload['image_data'];
         this.getZoomSlider().setValue(0, payload['zoom'], true);
@@ -137,6 +136,7 @@
             varname : this.payload['varname'],
             title: wd['title'],
         });
+        var newRefs = this.createMyRefs(this.plotWindowView.id);
         this.getColorbar().src = "data:image/png;base64," + wd['colorbar'];
         this.getFieldSelector().store = wd['fields'];
         this.getFieldSelector().value = wd['initial_field'];
@@ -154,7 +154,6 @@
         supportsParameterFiles: true,
         displayName: 'Do not use',
         preCreation: function(obj) {
-            examine = this;
             var widget = Ext.create(this.getName())
             var ts = widget.templateManager.applyObject(obj);
             function makeProj(b, e) {


diff -r 84c48a01f9947dcba9ac536d785c081ec050c01c -r 0878d2f2892b786970bb6ea33e2933bf0704f730 yt/gui/reason/html/app/view/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/view/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/view/widgets/PlotWindow.js
@@ -42,7 +42,7 @@
 
     items: [ 
         { xtype:'image',
-          id: 'image_panel',
+          itemId: 'image_panel',
           src: 'nothing.png',
           draggable: false,
           x: 100,
@@ -52,7 +52,7 @@
           draggable: false,
         }, {
             xtype:'image',
-            id: 'colorbar',
+            itemId: 'colorbar',
             src: 'nothing.png',
             style: 'border: 1px solid #000000;',
             x: 510,
@@ -61,7 +61,7 @@
             height: 400,
         }, {
             xtype: 'panel',
-            id: 'ticks',
+            itemId: 'ticks',
             layout: 'absolute',
             y: 0,
             x: 540,
@@ -70,7 +70,7 @@
             items : [],
             border: false,
         }, {   xtype: 'multislider',
-            id: 'zoomSlider',
+            itemId: 'zoomSlider',
             minValue: 0,
             maxValue: 100,
             increment: 0.1,
@@ -79,7 +79,7 @@
         },{
             xtype: 'combo',
             text: 'Field',
-            id: 'fieldSelector',
+            itemId: 'fieldSelector',
             x: 100,
             y: 435,
             width: 400,
@@ -92,28 +92,28 @@
         /* the single buttons for 10% pan*/
             xtype:'button',
             iconCls: 'singleuparrow',
-            id: 'singleuparrow',
+            itemId: 'singleuparrow',
             //text: 'North',
             x: 40,
             y: 10,
         }, {
             xtype:'button',
             iconCls: 'singlerightarrow',
-            id: 'singlerightarrow',
+            itemId: 'singlerightarrow',
             //text:'East',
             x : 60,
             y : 30,
         }, {
             xtype:'button',
             iconCls: 'singledownarrow',
-            id: 'singledownarrow',
+            itemId: 'singledownarrow',
             //text: 'South',
             x: 40,
             y: 50,
         }, {
             xtype: 'button',
             iconCls: 'singleleftarrow',
-            id: 'singleleftarrow',
+            itemId: 'singleleftarrow',
             //text: 'West',
             x: 20,
             y: 30,
@@ -122,14 +122,14 @@
         {
             xtype:'button',
             iconCls: 'doubleuparrow',
-            id:'doubleuparrow',
+            itemId:'doubleuparrow',
             //text: 'North',
             x: 40,
             y: 80,
         }, {
             xtype:'button',
             iconCls: 'doublerightarrow',
-            id:'doublerightarrow',
+            itemId:'doublerightarrow',
             //text:'East',
             x : 60,
             y : 100,
@@ -137,13 +137,13 @@
             xtype:'button',
             iconCls: 'doubledownarrow',
             //text: 'South',
-            id: 'doubledownarrow',
+            itemId: 'doubledownarrow',
             x: 40,
             y: 120,
         }, {
             xtype: 'button',
             iconCls: 'doubleleftarrow',
-            id: 'doubleleftarrow',
+            itemId: 'doubleleftarrow',
             //text: 'West',
             x: 20,
             y: 100,
@@ -152,35 +152,35 @@
         {
             xtype: 'button',
             text: 'Zoom In 10x',
-            id: "zoomin10x",
+            itemId: "zoomin10x",
             x: 10,
             y: 160,
             width: 80,
         },{
             xtype: 'button',
             text: 'Zoom In 2x',
-            id: "zoomin2x",
+            itemId: "zoomin2x",
             x: 10,
             y: 185,
             width: 80,
         },{
             xtype: 'button',
             text: 'Zoom Out 2x',
-            id:'zoomout2x',
+            itemId:'zoomout2x',
             x: 10,
             y: 210,
             width: 80,
         },{
             xtype: 'button',
             text: 'Zoom Out 10x',
-            id:'zoomout10x',
+            itemId:'zoomout10x',
             x: 10,
             y: 235,
             width: 80,
         },{
             xtype: 'button',
             text: 'Upload Image',
-            id: 'uploadimage',
+            itemId: 'uploadimage',
             x: 10,
             y: 285,
             width: 80,
@@ -189,7 +189,7 @@
         },{
             xtype: 'button',
             text: 'Pannable Map',
-            id: 'pannablemap',
+            itemId: 'pannablemap',
             x: 10,
             y: 335,
             width: 80,
@@ -197,7 +197,7 @@
         },{
             xtype: 'panel',
             layout: 'vbox',
-            id: 'rhs_panel',
+            itemId: 'rhs_panel',
             width: 250,
             height: 460,
             x: 690, y: 10,
@@ -209,20 +209,20 @@
                 {
                   xtype: 'panel',
                   title: 'Plot MetaData',
-                  id: 'metadataString',
+                  itemId: 'metadataString',
                   style: {fontFamily: '"Inconsolata", monospace'},
                   html: 'Welcome to the Plot Window.',
                   height: 200,
                 }, {
                   xtype: 'tabpanel',
-                  id: 'editor_panel',
+                  itemId: 'editor_panel',
                   flex: 1,
                   activeTab: 0,
                   items: [
                 {
                   xtype: 'panel',
                   title: 'Plot Editor',
-                  id: 'plot_edit',
+                  itemId: 'plot_edit',
                   style: {fontFamily: '"Inconsolata", monospace'},
                   layout: 'absolute',
                   flex: 1,
@@ -239,7 +239,7 @@
                        y: 20,
                        width : 80,
                        xtype: 'combo',
-                       id: 'transform',
+                       itemId: 'transform',
                        editable: false,
                        triggerAction: 'all',
                        validateOnBlur: false,
@@ -258,7 +258,7 @@
                        y: 60,
                        width : 140,
                        xtype: 'combo',
-                       id: 'colormap',
+                       itemId: 'colormap',
                        editable: false,
                        triggerAction: 'all',
                        validateOnBlur: false,
@@ -285,7 +285,7 @@
                 }, {
                   xtype: 'panel',
                   title: 'Contours',
-                  id: 'contour_edit',
+                  itemId: 'contour_edit',
                   style: {fontFamily: '"Inconsolata", monospace'},
                   layout: 'absolute',
                   flex: 1,
@@ -302,7 +302,7 @@
                        width : 160,
                        xtype: 'combo',
                        editable: false,
-                       id: 'contourfield',
+                       itemId: 'contourfield',
                        triggerAction: 'all',
                        validateOnBlur: false,
                        value: '',
@@ -318,7 +318,7 @@
                        y: 60,
                        width : 160,
                        xtype: 'slider',
-                       id: 'ncont',
+                       itemId: 'ncont',
                        minValue: 0,
                        maxValue: 10,
                        value: 5,
@@ -335,21 +335,21 @@
                        y: 100,
                        width : 160,
                        xtype: 'checkbox',
-                       id: 'logit',
+                       itemId: 'logit',
                        checked: true,
                      }, {
                        x: 10,
                        y: 180,
                        width: 80,
                        xtype: 'button',
-                       id: 'contourapply',
+                       itemId: 'contourapply',
                        text: 'Apply',
                      }
                   ]
                 }, {
                   xtype: 'panel',
                   title: 'Velocity Vectors',
-                  id: 'vector_edit',
+                  itemId: 'vector_edit',
                   style: {fontFamily: '"Inconsolata", monospace'},
                   layout: 'absolute',
                   flex: 1,
@@ -365,7 +365,7 @@
                        y: 60,
                        width : 160,
                        xtype: 'slider',
-                       id: 'skip',
+                       itemId: 'skip',
                        minValue: 1,
                        maxValue: 64,
                        value: 32,
@@ -376,7 +376,7 @@
                        y: 180,
                        width: 80,
                        xtype: 'button',
-                       id: 'vectorsapply',
+                       itemId: 'vectorsapply',
                        text: 'Apply',
                      }
                   ]


diff -r 84c48a01f9947dcba9ac536d785c081ec050c01c -r 0878d2f2892b786970bb6ea33e2933bf0704f730 yt/gui/reason/html/app/view/widgets/PlotWindowCreator.js
--- a/yt/gui/reason/html/app/view/widgets/PlotWindowCreator.js
+++ b/yt/gui/reason/html/app/view/widgets/PlotWindowCreator.js
@@ -47,7 +47,7 @@
               items: [{
                   xtype:'combo',
                   fieldLabel: 'Axis',
-                  id: 'axis',
+                  itemId: 'axis',
                   store:['X','Y','Z'],
                   width: 230,
                   allowBlank:false,
@@ -56,13 +56,13 @@
               },{
                   xtype:'checkbox',
                   fieldLabel: 'Center on Max',
-                  id: 'maxDens',
+                  itemId: 'maxDens',
                   width: 90,
                   allowBlank:false,
               },{
                   xtype:'combo',
                   fieldLabel: 'Field',
-                  id: 'field',
+                  itemId: 'field',
                   store: [],
                   width: 230,
                   allowBlank:false,
@@ -80,9 +80,9 @@
               }],
               buttons: [
                   {
-                      text: 'Project', id: 'create',
+                      text: 'Project', itemId: 'create',
                   },{
-                      text: 'Cancel', id: 'cancel',
+                      text: 'Cancel', itemId: 'cancel',
                   }
               ]
     }],



https://bitbucket.org/yt_analysis/yt/changeset/465de15cd0f1/
changeset:   465de15cd0f1
branch:      yt
user:        MatthewTurk
date:        2012-06-03 00:24:06
summary:      * Adding rdebug object
 * Adding possibly-useful validation option to event handling with widgets
 * Starting work on widget triggers that have additional JS code
 * Fixing layout on PlotWindow
affected #:  5 files

diff -r 0878d2f2892b786970bb6ea33e2933bf0704f730 -r 465de15cd0f1fe5a64389fcb995e119f927f354a yt/gui/reason/html/app.js
--- a/yt/gui/reason/html/app.js
+++ b/yt/gui/reason/html/app.js
@@ -31,7 +31,7 @@
 
 Ext.Loader.setConfig({enabled:true});
 
-var reason, examine;
+var reason, rdebug, examine;
 
 Ext.application({
     requires: ['Ext.container.Viewport',
@@ -45,6 +45,7 @@
 
     launch: function() {
         reason = this;
+        rdebug = this.getController("Debugger");
         Ext.create('Ext.container.Viewport', {
             layout: 'border',
             items: [
@@ -100,6 +101,7 @@
         'PayloadDirector',
         'WidgetDirector',
         'MenuActions',
+        'Debugger',
     ],
 
 });


diff -r 0878d2f2892b786970bb6ea33e2933bf0704f730 -r 465de15cd0f1fe5a64389fcb995e119f927f354a yt/gui/reason/html/app/controller/Debugger.js
--- /dev/null
+++ b/yt/gui/reason/html/app/controller/Debugger.js
@@ -0,0 +1,54 @@
+/**********************************************************************
+Debug helper for Reason
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define('Reason.controller.Debugger', {
+    extend: 'Ext.app.Controller',
+    stores: ['WidgetTypes', 'WidgetInstances'],
+
+    getWidget: function(widgetId) {
+        this.getWidgetInstancesStore().find(
+            {'widgetid': widgetId});
+        var widgetInfo = this.getWidgetInstancesStore().getAt(resultId).data;
+        return widgetInfo.widget;
+    },
+
+    getAllWidgetsByType: function(typeName) {
+        var arr = []
+        this.getWidgetInstancesStore().each(function(r) {
+            if (r.data['widgettype'] == typeName) {
+                arr.push(r.data);
+            }
+        });
+        return arr;
+    },
+
+});
+


diff -r 0878d2f2892b786970bb6ea33e2933bf0704f730 -r 465de15cd0f1fe5a64389fcb995e119f927f354a yt/gui/reason/html/app/controller/widgets/BaseWidget.js
--- a/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
+++ b/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
@@ -32,6 +32,7 @@
     templateManager: null,
     templates: {},
     executionTriggers: [],
+    widgetTriggers: [],
 
     constructor: function() {
         this.templateManager = Ext.create(
@@ -41,15 +42,17 @@
         this.callParent(arguments);
     },
 
-    getExecuteFunction: function(ww, templateName) {
+    getExecuteFunction: function(ww, templateName, isValidFn) {
         var tpl = new Ext.XTemplate(
             this.templateManager.getTemplates()[templateName]);
         var args = {};
         function ev() {
+            console.log("Inside ... " + templateName);
             Ext.each(arguments, function(v, i) {
                 args["a" + i] = arguments[i];
             });
             args['widget'] = ww;
+            if((isValidFn != null) && (isValidFn(arguments) == false)) {return;}
             yt_rpc.ExtDirectREPL.execute({
                 code: tpl.apply(args),
                 hide: true}, Ext.emptyFn);
@@ -59,15 +62,14 @@
 
     applyExecuteHandlers: function(ww) {
         var conf;
-        function ef(id, ename, tpl) {
+        function ef(id, ename, tpl, isValidFn) {
             conf = {}
             conf[ename] = this.getExecuteFunction(ww, tpl);
-            console.log("Adding " + ename + " " + id);
             ww.query(id)[0].on(conf);
         };
         Ext.each(this.executionTriggers, function(trigger) {
-            /*console.log(trigger[0] + " " + trigger[1] + " " + trigger[2]);*/
-            ef.call(this, trigger[0], trigger[1], trigger[2]);
+            /*console.log(trigger[0] + " " + trigger[1] + " " + trigger[2], trigger[3]);*/
+            ef.call(this, trigger[0], trigger[1], trigger[2], trigger[3]);
         }, this);
     },
 


diff -r 0878d2f2892b786970bb6ea33e2933bf0704f730 -r 465de15cd0f1fe5a64389fcb995e119f927f354a yt/gui/reason/html/app/controller/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
@@ -62,12 +62,15 @@
                          ' {widget.getLogit().getValue():capitalize})',
         adjustVectors:   '{widget.varname}.set_vector_info(' +
                          '{widget.getVectorSkip()})',
+        recenterImage:   '{widget.varname}.image_recenter(' +
+                         '{x}, {y}, {w}, {h})',
     },
 
     widgetTriggers: [
-        ['upload_image'],
-        ['pannable_map'],
-        ['clickanddrag'],
+        ['uploadimage', 'click', 'uploadImage'],
+        ['pannablemap', 'click', 'createPannableMap'],
+        ['imagepanel', 'click', 'recenterImage'],
+        ['imagepanel', 'afterrender', 'setupDragImage'],
     ],
 
     executionTriggers: [
@@ -180,4 +183,42 @@
         },
 
     },
+
+    uploadImage: function() {
+        var imageData = this.getImage().dom.src;
+        var mds = this.getMetadataString();
+        yt_rpc.ExtDirectREPL.upload_image(
+            {image_data:imageData, caption:metadata_string},
+            function(rv) {
+                var alert_text;
+                if(rv['uploaded'] == false) {
+                    alert_text = "Failure uploading image!";
+                } else {
+                    alert_text = "Uploaded to " +
+                            rv['upload']['links']['imgur_page'];
+                }
+                Ext.Msg.alert('imgur.com', alert_text);
+                reason.fireEvent("logentry", alert_text);
+            });
+    },
+
+    createPannableMap: function() {
+        alert("Not implemented!");
+    },
+
+    recenterImage: function(e) {
+        if (e.ctrlKey == false) return;
+        tpl = this.templateManager.getTemplates()["recenter"]
+        var args = {widget: this.plotWindowView,
+                    x: xy[0], y: xy[1],
+                    w: this.getImage().dom.width,
+                    w: this.getImage().dom.height};
+        yt_rpc.ExtDirectREPL.execute(
+            {code:tpl.apply(args), hide:true},
+            Ext.emptyFn);
+    },
+
+    setupDragImage: function() {
+
+    },
 });


diff -r 0878d2f2892b786970bb6ea33e2933bf0704f730 -r 465de15cd0f1fe5a64389fcb995e119f927f354a yt/gui/reason/html/app/view/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/view/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/view/widgets/PlotWindow.js
@@ -196,14 +196,14 @@
             tooltip: "Open a pannable map in a new tab",
         },{
             xtype: 'panel',
-            layout: 'vbox',
             itemId: 'rhs_panel',
-            width: 250,
+            width: 300,
             height: 460,
-            x: 690, y: 10,
-            layoutConfig: {
-                align: 'stretch',
-                pack: 'start',
+            x: 590, y: 10,
+            layout: {
+                type: 'vbox',
+                align:'stretch',
+                pack:'start',
             },
             items: [
                 {
@@ -216,7 +216,7 @@
                 }, {
                   xtype: 'tabpanel',
                   itemId: 'editor_panel',
-                  flex: 1,
+                  flex: 1.0,
                   activeTab: 0,
                   items: [
                 {



https://bitbucket.org/yt_analysis/yt/changeset/5f29137218b2/
changeset:   5f29137218b2
branch:      yt
user:        MatthewTurk
date:        2012-06-04 13:30:43
summary:     Starting to implement widget triggers.  Added new ability to just get a single
template applied to an object.
affected #:  4 files

diff -r 465de15cd0f1fe5a64389fcb995e119f927f354a -r 5f29137218b2a4e729c3aa145a1f190a328036d3 yt/gui/reason/html/app.js
--- a/yt/gui/reason/html/app.js
+++ b/yt/gui/reason/html/app.js
@@ -73,7 +73,6 @@
                         type: 'anchor',
                     },
                     items: [
-                        { xtype: 'mainmenu' },
                         { xtype: 'dataobjecttree', },
                     ],
               }, {
@@ -81,6 +80,10 @@
                 region: 'center',
                 id: 'center-panel',
                 activeTab: 0,
+                dockedItems: [ {
+                    dock: 'top',
+                    xtype: 'mainmenu',
+                } ],
                 items: [
                 { xtype: 'panel',
                   title: 'Welcome!',


diff -r 465de15cd0f1fe5a64389fcb995e119f927f354a -r 5f29137218b2a4e729c3aa145a1f190a328036d3 yt/gui/reason/html/app/controller/widgets/BaseWidget.js
--- a/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
+++ b/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
@@ -46,13 +46,16 @@
         var tpl = new Ext.XTemplate(
             this.templateManager.getTemplates()[templateName]);
         var args = {};
+        var control = this;
         function ev() {
             console.log("Inside ... " + templateName);
             Ext.each(arguments, function(v, i) {
                 args["a" + i] = arguments[i];
             });
+            args['control'] = control;
             args['widget'] = ww;
             if((isValidFn != null) && (isValidFn(arguments) == false)) {return;}
+            examine = {args: args, code: tpl.apply(args)};
             yt_rpc.ExtDirectREPL.execute({
                 code: tpl.apply(args),
                 hide: true}, Ext.emptyFn);
@@ -71,6 +74,11 @@
             /*console.log(trigger[0] + " " + trigger[1] + " " + trigger[2], trigger[3]);*/
             ef.call(this, trigger[0], trigger[1], trigger[2], trigger[3]);
         }, this);
+        Ext.each(this.widgetTriggers, function(trigger) {
+            conf = {}
+            conf[trigger[1]] = this[trigger[2]];
+            ww.query(trigger[0])[0].on(conf);
+        }, this);
     },
 
     createMyRefs: function(varname) {


diff -r 465de15cd0f1fe5a64389fcb995e119f927f354a -r 5f29137218b2a4e729c3aa145a1f190a328036d3 yt/gui/reason/html/app/controller/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
@@ -57,19 +57,19 @@
                          '{widget.varname}._current_field, ' +
                          '"{a1.data[\'field1\']}")',
         adjustContours:  '{widget.varname}.set_contour_info(' +
-                         '"{widget.getContourField().getValue()}",' +
-                         ' {widget.getNcont().getValue()},' +
-                         ' {widget.getLogit().getValue():capitalize})',
+                         '"{[control.getContourField().getValue()]}",' +
+                         ' {[control.getNcont().getValue()]},' +
+                         ' {[control.getLogit().getValue()]:capitalize})',
         adjustVectors:   '{widget.varname}.set_vector_info(' +
-                         '{widget.getVectorSkip()})',
+                         '{[control.getVectorSkip()]})',
         recenterImage:   '{widget.varname}.image_recenter(' +
                          '{x}, {y}, {w}, {h})',
+        dragImage:       '{widget.varname}.pan_rel(({rel_x}, {rel_y}))',
     },
 
     widgetTriggers: [
         ['uploadimage', 'click', 'uploadImage'],
         ['pannablemap', 'click', 'createPannableMap'],
-        ['imagepanel', 'click', 'recenterImage'],
         ['imagepanel', 'afterrender', 'setupDragImage'],
     ],
 
@@ -158,7 +158,6 @@
         displayName: 'Do not use',
         preCreation: function(obj) {
             var widget = Ext.create(this.getName())
-            var ts = widget.templateManager.applyObject(obj);
             function makeProj(b, e) {
                 reason.fireEvent("disableinput");
                 yt_rpc.ExtDirectREPL.create_proj({
@@ -170,7 +169,8 @@
                 }, function() { examine = arguments; });
                 win.destroy();
             }
-            win = Ext.widget("plotwindowcreator", {title:ts.pwt, obj:obj});
+            var title = widget.templateManager.applyObject(obj, 'pwt');
+            win = Ext.widget("plotwindowcreator", {title:title, obj:obj});
             win.query("#weightField")[0].store = 
                 ['None'].concat(obj.field_list);
             win.query("#field")[0].store = obj.field_list;
@@ -206,19 +206,37 @@
         alert("Not implemented!");
     },
 
-    recenterImage: function(e) {
-        if (e.ctrlKey == false) return;
-        tpl = this.templateManager.getTemplates()["recenter"]
-        var args = {widget: this.plotWindowView,
-                    x: xy[0], y: xy[1],
-                    w: this.getImage().dom.width,
-                    w: this.getImage().dom.height};
-        yt_rpc.ExtDirectREPL.execute(
-            {code:tpl.apply(args), hide:true},
-            Ext.emptyFn);
-    },
-
-    setupDragImage: function() {
-
+    setupDragImage: function(c) {
+        var control = this;
+        var dragStartPos, dragStopPos;
+        c.el.on('click',  function(e) {
+            if (e.ctrlKey == false) return;
+            tpl = control.templateManager.getTemplates()["recenter"]
+            var args = {widget: control.plotWindowView,
+                        x: xy[0], y: xy[1],
+                        w: control.getImage().dom.width,
+                        w: control.getImage().dom.height};
+            yt_rpc.ExtDirectREPL.execute(
+                {code:tpl.apply(args), hide:true},
+                Ext.emptyFn);
+        });
+        c.el.on('mousedown', function(e){
+            dragStartPos = e.getXY();
+        });
+        c.el.on('mouseup', function(e){
+            dragStopPos = e.getXY();
+            deltaX = dragStopPos[0] - c.dragStartPos[0];
+            deltaY = dragStopPos[1] - c.dragStartPos[1];
+            if (((deltaX < -10) || (deltaX > 10)) ||
+                ((deltaY < -10) || (deltaY > 10))) {
+                rel_x = -deltaX / 400;
+                rel_y = -deltaY / 400;
+                tpl = control.templateManager.getTemplates()["recenter"]
+                var args = {widget: control.plotWindowView,
+                            rel_x: rel_x, rel_y: rel_y};
+                yt_rpc.ExtDirectREPL.execute(
+                    {code:tpl.apply(args), hide:true}, Ext.emptyFn()); 
+            }
+        });
     },
 });


diff -r 465de15cd0f1fe5a64389fcb995e119f927f354a -r 5f29137218b2a4e729c3aa145a1f190a328036d3 yt/gui/reason/html/app/templates/TemplateContainer.js
--- a/yt/gui/reason/html/app/templates/TemplateContainer.js
+++ b/yt/gui/reason/html/app/templates/TemplateContainer.js
@@ -39,9 +39,13 @@
         templates : {},
     },
 
-    applyObject: function(obj) {
+    applyObject: function(obj, tname) {
         var applied = {};
         var tpl;
+        if (tname != null){
+            tpl = new Ext.XTemplate(this.getTemplates()[tname]);
+            return tpl.apply(obj);
+        }
         Ext.iterate(this.getTemplates(), function(k, v, o){
             tpl = new Ext.XTemplate(v);
             applied[k] = tpl.apply(obj);



https://bitbucket.org/yt_analysis/yt/changeset/24597a575cf0/
changeset:   24597a575cf0
branch:      yt
user:        MatthewTurk
date:        2012-06-04 14:28:12
summary:     Removing a bunch of "examine = " lines and removing the drag event handlers;
they don't work that well and they're obsoleted by the pannable map.
Ctrl-click to recenter now works.
affected #:  4 files

diff -r 5f29137218b2a4e729c3aa145a1f190a328036d3 -r 24597a575cf0773ad88932262022f43645f9a7e3 yt/gui/reason/html/app/controller/WidgetDirector.js
--- a/yt/gui/reason/html/app/controller/WidgetDirector.js
+++ b/yt/gui/reason/html/app/controller/WidgetDirector.js
@@ -71,7 +71,6 @@
         var w;
         this.getWidgetTypesStore().each(function(record, idx) {
             w = record.data;
-            examine = w;
             if (((data.type == 'parameter_file') && (w.pfs  == false)) 
              || ((data.type != 'parameter_file') && (w.objs == false))) {
               return;
@@ -123,7 +122,6 @@
     sendPayload: function(payload) {
         var resultId = this.getWidgetInstancesStore().find(
             'widgetid', payload['widget_id']);
-        examine = payload;
         if (resultId == -1) {
             Ext.Error.raise('Could not find widget "' +
                             payload['widget_id'] + '".');
@@ -131,7 +129,6 @@
         console.log("Directing payload for " + payload['widget_id'] +
                     " to resultId " + resultId);
         var widgetInfo = this.getWidgetInstancesStore().getAt(resultId).data;
-        examine = widgetInfo;
         widgetInfo['widget'].applyPayload(payload);
     },
 


diff -r 5f29137218b2a4e729c3aa145a1f190a328036d3 -r 24597a575cf0773ad88932262022f43645f9a7e3 yt/gui/reason/html/app/controller/widgets/BaseWidget.js
--- a/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
+++ b/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
@@ -55,7 +55,6 @@
             args['control'] = control;
             args['widget'] = ww;
             if((isValidFn != null) && (isValidFn(arguments) == false)) {return;}
-            examine = {args: args, code: tpl.apply(args)};
             yt_rpc.ExtDirectREPL.execute({
                 code: tpl.apply(args),
                 hide: true}, Ext.emptyFn);
@@ -75,7 +74,8 @@
             ef.call(this, trigger[0], trigger[1], trigger[2], trigger[3]);
         }, this);
         Ext.each(this.widgetTriggers, function(trigger) {
-            conf = {}
+            console.log(trigger[0], trigger[1], trigger[2]);
+            conf = {scope:this}
             conf[trigger[1]] = this[trigger[2]];
             ww.query(trigger[0])[0].on(conf);
         }, this);


diff -r 5f29137218b2a4e729c3aa145a1f190a328036d3 -r 24597a575cf0773ad88932262022f43645f9a7e3 yt/gui/reason/html/app/controller/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
@@ -68,9 +68,9 @@
     },
 
     widgetTriggers: [
-        ['uploadimage', 'click', 'uploadImage'],
-        ['pannablemap', 'click', 'createPannableMap'],
-        ['imagepanel', 'afterrender', 'setupDragImage'],
+        ['#uploadimage', 'click', 'uploadImage'],
+        ['#pannablemap', 'click', 'createPannableMap'],
+        ['#imagepanel', 'afterrender', 'setupClickImage'],
     ],
 
     executionTriggers: [
@@ -96,7 +96,7 @@
 
     viewRefs: [
         { ref: 'colorbar', selector: '#colorbar'},
-        { ref: 'image', selector: '#image_panel'},
+        { ref: 'image', selector: '#imagepanel'},
         { ref: 'fieldSelector', selector: '#fieldSelector'},
         { ref: 'transform', selector: '#transform'},
         { ref: 'contourField', selector: '#contourfield'},
@@ -206,37 +206,22 @@
         alert("Not implemented!");
     },
 
-    setupDragImage: function(c) {
-        var control = this;
-        var dragStartPos, dragStopPos;
+    setupClickImage: function(c) {
+        var controller = this;
+        var dragStartPos = {x:-1, y:-1};
         c.el.on('click',  function(e) {
             if (e.ctrlKey == false) return;
-            tpl = control.templateManager.getTemplates()["recenter"]
-            var args = {widget: control.plotWindowView,
-                        x: xy[0], y: xy[1],
-                        w: control.getImage().dom.width,
-                        w: control.getImage().dom.height};
+            var xy = e.getXY();
+            var args = {widget: controller.plotWindowView,
+                        x: xy[0] - controller.getImage().getEl().dom.x,
+                        y: xy[1] - controller.getImage().getEl().dom.y,
+                        w: controller.getImage().width,
+                        h: controller.getImage().height};
+            var code = controller.templateManager.applyObject(
+                        args, "recenterImage");
             yt_rpc.ExtDirectREPL.execute(
-                {code:tpl.apply(args), hide:true},
+                {code:code, hide:true},
                 Ext.emptyFn);
         });
-        c.el.on('mousedown', function(e){
-            dragStartPos = e.getXY();
-        });
-        c.el.on('mouseup', function(e){
-            dragStopPos = e.getXY();
-            deltaX = dragStopPos[0] - c.dragStartPos[0];
-            deltaY = dragStopPos[1] - c.dragStartPos[1];
-            if (((deltaX < -10) || (deltaX > 10)) ||
-                ((deltaY < -10) || (deltaY > 10))) {
-                rel_x = -deltaX / 400;
-                rel_y = -deltaY / 400;
-                tpl = control.templateManager.getTemplates()["recenter"]
-                var args = {widget: control.plotWindowView,
-                            rel_x: rel_x, rel_y: rel_y};
-                yt_rpc.ExtDirectREPL.execute(
-                    {code:tpl.apply(args), hide:true}, Ext.emptyFn()); 
-            }
-        });
     },
 });


diff -r 5f29137218b2a4e729c3aa145a1f190a328036d3 -r 24597a575cf0773ad88932262022f43645f9a7e3 yt/gui/reason/html/app/view/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/view/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/view/widgets/PlotWindow.js
@@ -42,9 +42,8 @@
 
     items: [ 
         { xtype:'image',
-          itemId: 'image_panel',
+          itemId: 'imagepanel',
           src: 'nothing.png',
-          draggable: false,
           x: 100,
           y: 10,
           width: 400,



https://bitbucket.org/yt_analysis/yt/changeset/625fdd3d6976/
changeset:   625fdd3d6976
branch:      yt
user:        MatthewTurk
date:        2012-06-04 23:08:00
summary:     Renaming payload director to server communication and removing usage of direct
calls to yt_rpc.  This should help in the future if we port to a different
execution model.  Porting the grid data viewer.
affected #:  12 files

diff -r 24597a575cf0773ad88932262022f43645f9a7e3 -r 625fdd3d6976fea299c41973b5df075cfd35bcdf yt/gui/reason/html/app.js
--- a/yt/gui/reason/html/app.js
+++ b/yt/gui/reason/html/app.js
@@ -46,6 +46,7 @@
     launch: function() {
         reason = this;
         rdebug = this.getController("Debugger");
+        this.server = this.getController("ServerCommunication");
         Ext.create('Ext.container.Viewport', {
             layout: 'border',
             items: [
@@ -101,7 +102,7 @@
         'Logging',
         'DataObjects',
         'Notebook',
-        'PayloadDirector',
+        'ServerCommunication',
         'WidgetDirector',
         'MenuActions',
         'Debugger',


diff -r 24597a575cf0773ad88932262022f43645f9a7e3 -r 625fdd3d6976fea299c41973b5df075cfd35bcdf yt/gui/reason/html/app/controller/MenuActions.js
--- a/yt/gui/reason/html/app/controller/MenuActions.js
+++ b/yt/gui/reason/html/app/controller/MenuActions.js
@@ -65,7 +65,7 @@
         Ext.Msg.prompt("We have important work to do.", "Enter filename.", 
             function(btn, text) {
                 if (btn == 'ok') {
-                    yt_rpc.ExtDirectREPL.save_session(
+                    reason.server.method('save_session',
                         {filename:text}, handleResponse);
                 }
             }
@@ -82,7 +82,7 @@
     },
 
     pastebinScript: function(b, e) {
-        yt_rpc.ExtDirectREPL.paste_session({}, function(f, a) {
+        reason.server('paste_session', {}, function(f, a) {
             if (a.result['status'] == 'SUCCESS') {
                 var alert_text = 'Pasted session to:<br>' + 
                 a.result['site']
@@ -100,7 +100,7 @@
 
     quitReason: function(b, e) {
         this.application.fireEvent("stopheartbeat");
-        yt_rpc.ExtDirectREPL.shutdown({}, function(f,a) { 
+        reason.server('shutdown', {}, function(f, a) {
         Ext.Msg.alert("Goodbye!", "Goodbye from Reason!", function() {
         window.open("http://www.google.com/", "_top");});});
     },


diff -r 24597a575cf0773ad88932262022f43645f9a7e3 -r 625fdd3d6976fea299c41973b5df075cfd35bcdf yt/gui/reason/html/app/controller/Notebook.js
--- a/yt/gui/reason/html/app/controller/Notebook.js
+++ b/yt/gui/reason/html/app/controller/Notebook.js
@@ -85,7 +85,7 @@
     executeCell: function(line) {
         this.application.fireEvent("blockinput");
         console.log("Asked to execute " + line);
-        yt_rpc.ExtDirectREPL.execute({code:line}, this.cellExecuted);
+        reason.server.execute(line, false);
     },
 
     scrollToBottom: function() {
@@ -110,8 +110,5 @@
         var application = this.application;
     },
 
-    cellExecuted: function(result) {
-        console.log("Cell Executed!");
-    },
 });
 


diff -r 24597a575cf0773ad88932262022f43645f9a7e3 -r 625fdd3d6976fea299c41973b5df075cfd35bcdf yt/gui/reason/html/app/controller/PayloadDirector.js
--- a/yt/gui/reason/html/app/controller/PayloadDirector.js
+++ /dev/null
@@ -1,105 +0,0 @@
-/**********************************************************************
-The Payload handling facility for Reason
-
-Author: Cameron Hummels <chummels at gmail.com>
-Affiliation: Columbia
-Author: Jeffrey S. Oishi <jsoishi at gmail.com>
-Affiliation: KIPAC/SLAC/Stanford
-Author: Britton Smith <brittonsmith at gmail.com>
-Affiliation: MSU
-Author: Matthew Turk <matthewturk at gmail.com>
-Affiliation: Columbia University
-Homepage: http://yt-project.org/
-License:
-  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
-
-  This file is part of yt.
-
-  yt is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 3 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-***********************************************************************/
-
-var heartbeatRequest = false;
-
-Ext.define('Reason.controller.PayloadDirector', {
-    extend: 'Ext.app.Controller',
-    stores: ['Payloads'],
-    views: ['PayloadGrid'],
-
-    init: function() {
-        this.application.addListener({
-            payloadreceived: {fn: this.handlePayload, scope: this},
-            stopheartbeat: {fn: this.stopHeartbeat, scope: this},
-            enabledebug: {fn: this.enableDebug, scope: this},
-        })
-        /* We also use this as our heartbeat */
-        this.taskRunner = new Ext.util.TaskRunner();
-        heartbeatRequest = false;
-        this.heartbeat = this.taskRunner.start(
-            {run: this.heartbeatCall,
-             interval: 250});
-        this.heartbeat = this.taskRunner.start(
-            {run: this.dataObjectsCall,
-             interval: 5000});
-        this.callParent(arguments);
-    },
-    handlePayload: function(payload) {
-        if ((this.payloadGrid) && (payload['type'] != 'logentry')) {
-            var wv = payload['varname'];
-            if (payload['type'] == 'widget_payload') {
-                wv = payload['widget_id'];
-            }
-            this.getPayloadsStore().add({
-                payloadtype: payload['type'],
-                widgettype: payload['widget_type'],
-                varname: wv,
-            });
-        }
-        this.application.fireEvent('payload' + payload['type'], payload);
-    },
-
-    dataObjectsCall: function() {
-        yt_rpc.ExtDirectParameterFileList.get_list_of_pfs({}, 
-            function(f, a) {
-                if (f == null) { return; }
-                reason.fireEvent("newdataobjects", f);
-        });
-    },
-
-    heartbeatCall: function() {
-        if (heartbeatRequest == true) return;
-        heartbeatRequest = true;
-        yt_rpc.ExtDirectREPL.heartbeat(
-            {}, function(f, a) {
-                heartbeatRequest = false;
-                if (f != null) { 
-                    Ext.each(f, function(payload, index) {
-                            reason.fireEvent("payloadreceived", payload);
-                    });
-                }
-                return true;
-            }
-        );
-    },
-
-    stopHeartbeat: function() {
-        this.taskRunner.stopAll();
-    },
-
-    enableDebug: function() {
-        this.payloadGrid = Ext.widget("payloadgrid");
-        Ext.ComponentQuery.query("viewport > #center-panel")[0].add(
-            this.payloadGrid);
-    }
-});
-


diff -r 24597a575cf0773ad88932262022f43645f9a7e3 -r 625fdd3d6976fea299c41973b5df075cfd35bcdf yt/gui/reason/html/app/controller/ServerCommunication.js
--- /dev/null
+++ b/yt/gui/reason/html/app/controller/ServerCommunication.js
@@ -0,0 +1,150 @@
+/**********************************************************************
+The Payload handling facility for Reason
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+var heartbeatRequest = false;
+
+Ext.define('Reason.controller.ServerCommunication', {
+    extend: 'Ext.app.Controller',
+    stores: ['Payloads'],
+    views: ['PayloadGrid'],
+
+    init: function() {
+        this.application.addListener({
+            payloadreceived: {fn: this.handlePayload, scope: this},
+            stopheartbeat: {fn: this.stopHeartbeat, scope: this},
+            enabledebug: {fn: this.enableDebug, scope: this},
+        })
+        /* We also use this as our heartbeat */
+        this.taskRunner = new Ext.util.TaskRunner();
+        heartbeatRequest = false;
+        this.heartbeat = this.taskRunner.start(
+            {run: this.heartbeatCall,
+             interval: 250});
+        this.heartbeat = this.taskRunner.start(
+            {run: this.dataObjectsCall,
+             interval: 5000});
+        this.callParent(arguments);
+    },
+
+    handlePayload: function(payload) {
+        if ((this.payloadGrid) && (payload['type'] != 'logentry')) {
+            var wv = payload['varname'];
+            if (payload['type'] == 'widget_payload') {
+                wv = payload['widget_id'];
+            }
+            this.getPayloadsStore().add({
+                payloadtype: payload['type'],
+                widgettype: payload['widget_type'],
+                varname: wv,
+            });
+        }
+        this.application.fireEvent('payload' + payload['type'], payload);
+    },
+
+    dataObjectsCall: function() {
+        yt_rpc.ExtDirectParameterFileList.get_list_of_pfs({}, 
+            function(f, a) {
+                if (f == null) { return; }
+                reason.fireEvent("newdataobjects", f);
+        });
+    },
+
+    heartbeatCall: function() {
+        if (heartbeatRequest == true) return;
+        heartbeatRequest = true;
+        yt_rpc.ExtDirectREPL.heartbeat(
+            {}, function(f, a) {
+                heartbeatRequest = false;
+                if (f != null) { 
+                    Ext.each(f, function(payload, index) {
+                            reason.fireEvent("payloadreceived", payload);
+                    });
+                }
+                return true;
+            }
+        );
+    },
+
+    stopHeartbeat: function() {
+        this.taskRunner.stopAll();
+    },
+
+    enableDebug: function() {
+        this.payloadGrid = Ext.widget("payloadgrid");
+        Ext.ComponentQuery.query("viewport > #center-panel")[0].add(
+            this.payloadGrid);
+    },
+
+    execute: function(code, hide, callback) {
+        var fn;
+        if (callback) { fn = callback; }
+        else { fn = this.returnFromRPC; }
+        if (hide == null) { hide = false; }
+        reason.fireEvent("disableinput");
+        yt_rpc.ExtDirectREPL.execute({code: code, hide:hide}, fn);
+    },
+
+    returnFromRPC: function(result, e) {
+        if(!e.status) {
+            var tpl = new Ext.XTemplate(
+                'RPC Error: {message}; {action}, {method}');
+            var trans = e.getTransaction();
+            tpl = tpl.apply({message: e.message,
+                             action: trans.action,
+                             method: trans.method});
+            Ext.Msg.alert("Error", tpl);
+            examine = {result: result, e: e};
+            Ext.Error.raise(tpl);
+        }
+        reason.fireEvent("allowinput");
+    },
+
+    method: function(methodName, args, callback) {
+        var m = yt_rpc.ExtDirectREPL[methodName];
+        if (!m) {
+            var t = "Could not identify method " + methodName;
+            Ext.Msg.alert("Error", t);
+            examine = {result: result, e: e};
+            Ext.Error.raise(t);
+        }
+        var fn;
+        if (callback) { fn = callback; }
+        else {
+            this.application.fireEvent("disableinput");
+            fn = this.returnFromRPC;
+        }
+        m(args, fn);
+    },
+
+    m: function() { return this.method(arguments); }
+
+});
+


diff -r 24597a575cf0773ad88932262022f43645f9a7e3 -r 625fdd3d6976fea299c41973b5df075cfd35bcdf yt/gui/reason/html/app/controller/WidgetDirector.js
--- a/yt/gui/reason/html/app/controller/WidgetDirector.js
+++ b/yt/gui/reason/html/app/controller/WidgetDirector.js
@@ -28,6 +28,7 @@
     requires: ["Reason.controller.widgets.SampleWidget",
                "Reason.controller.widgets.PlotWindow",
                "Reason.controller.widgets.ProgressBar",
+               "Reason.controller.widgets.GridDataViewer",
     ],
     stores: ['WidgetTypes', 'WidgetInstances'],
     views: ['WidgetTypesGrid', 'WidgetInstancesGrid'],
@@ -126,8 +127,8 @@
             Ext.Error.raise('Could not find widget "' +
                             payload['widget_id'] + '".');
         }
-        console.log("Directing payload for " + payload['widget_id'] +
-                    " to resultId " + resultId);
+        /*console.log("Directing payload for " + payload['widget_id'] +
+                    " to resultId " + resultId);*/
         var widgetInfo = this.getWidgetInstancesStore().getAt(resultId).data;
         widgetInfo['widget'].applyPayload(payload);
     },


diff -r 24597a575cf0773ad88932262022f43645f9a7e3 -r 625fdd3d6976fea299c41973b5df075cfd35bcdf yt/gui/reason/html/app/controller/widgets/BaseWidget.js
--- a/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
+++ b/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
@@ -55,9 +55,7 @@
             args['control'] = control;
             args['widget'] = ww;
             if((isValidFn != null) && (isValidFn(arguments) == false)) {return;}
-            yt_rpc.ExtDirectREPL.execute({
-                code: tpl.apply(args),
-                hide: true}, Ext.emptyFn);
+            reason.server.execute(tpl.apply(args), true);
         };
         return ev;
     },


diff -r 24597a575cf0773ad88932262022f43645f9a7e3 -r 625fdd3d6976fea299c41973b5df075cfd35bcdf yt/gui/reason/html/app/controller/widgets/GridDataViewer.js
--- a/yt/gui/reason/html/app/controller/widgets/GridDataViewer.js
+++ b/yt/gui/reason/html/app/controller/widgets/GridDataViewer.js
@@ -24,123 +24,53 @@
 ***********************************************************************/
 
 // shim layer with setTimeout fallback
-var WidgetGridDataViewer = function(python_varname, widget_data) {
-    this.id = python_varname;
-    this.widget_data = widget_data;
-    store = new Ext.data.ArrayStore({
-        fields: [
-           {name: 'grid_id', type:'int'},
-           {name: 'level', type:'int'},
-           {name: 'left_edge_x', type: 'float'},
-           {name: 'left_edge_y', type: 'float'},
-           {name: 'left_edge_z', type: 'float'},
-           {name: 'right_edge_x', type: 'float'},
-           {name: 'right_edge_y', type: 'float'},
-           {name: 'right_edge_z', type: 'float'},
-           {name: 'dim_x', type: 'int'},
-           {name: 'dim_y', type: 'int'},
-           {name: 'dim_z', type: 'int'},
-           {name: 'cells', type: 'int'},
-        ]
-    });
-    store.loadData(widget_data['gridvals']);
-    examine = widget_data;
+Ext.define("Reason.controller.widgets.GridDataViewer", {
+    extend: 'Reason.controller.widgets.BaseWidget',
+    requires: ['Reason.view.widgets.GridDataViewer'],
 
-    viewport.get("center-panel").add(
-        {
-            xtype: 'panel',
-            id: "gg_" + python_varname,
-            title: "Grid Data Viewer",
-            iconCls: 'graph',
-            autoScroll: true,
-            layout:'vbox',
-            layoutConfig: {align: 'stretch', pack: 'start'},
-            closable: true,
-            items: [ {
-                       xtype: 'grid',
-                       store: store,
-                       columns: [
-                            {
-                                id: 'grid_id',
-                                header: 'Grid ID',
-                                width: 100,
-                                dataIndex: 'grid_id',
-                                sortable: true,
-                            }, {
-                                id: 'left_edge_x',
-                                header: 'Left Edge x',
-                                width: 100,
-                                dataIndex: 'left_edge_x',
-                                sortable: true,
-                            }, {
-                                id: 'left_edge_y',
-                                header: 'Left Edge y',
-                                width: 100,
-                                dataIndex: 'left_edge_y',
-                                sortable: true,
-                            }, {
-                                id: 'left_edge_z',
-                                header: 'Left Edge z',
-                                width: 100,
-                                dataIndex: 'left_edge_z',
-                                sortable: true,
-                            }, {
-                                id: 'right_edge_x',
-                                header: 'Right Edge x',
-                                width: 100,
-                                dataIndex: 'right_edge_x',
-                                sortable: true,
-                            }, {
-                                id: 'right_edge_y',
-                                header: 'Right Edge y',
-                                width: 100,
-                                dataIndex: 'right_edge_y',
-                                sortable: true,
-                            }, {
-                                id: 'right_edge_z',
-                                header: 'Right Edge z',
-                                width: 100,
-                                dataIndex: 'right_edge_z',
-                                sortable: true,
-                            }, {
-                                id: 'dim_x',
-                                header: 'DimX',
-                                width: 100,
-                                dataIndex: 'dim_x',
-                                sortable: true,
-                            }, {
-                                id: 'dim_y',
-                                header: 'DimY',
-                                width: 100,
-                                dataIndex: 'dim_y',
-                                sortable: true,
-                            }, {
-                                id: 'dim_z',
-                                header: 'DimZ',
-                                width: 100,
-                                dataIndex: 'dim_z',
-                                sortable: true,
-                            }, {
-                                id: 'cells',
-                                header: 'Cells',
-                                width: 100,
-                                dataIndex: 'cells',
-                                sortable: true,
-                            },
-                       ],
-                      flex: 1,
-                      }
-                   ],
+    templates: {
+        title: "Grid Data for {widget.varname}",
+    },
 
-        }
-    );
+    widgetTriggers: [
 
-    viewport.get("center-panel").activate("gg_" + this.id);
-    viewport.doLayout();
-    this.panel = viewport.get("center-panel").get("gg_" + python_varname);
-    this.panel.doLayout();
+    ],
 
-    this.accept_results = function(payload) { }
-}
+    executionTriggers: [
 
-widget_types['grid_data'] = WidgetGridDataViewer;
+    ],
+
+    viewRefs: [
+
+    ],
+
+    applyPayload: function(payload) {
+        return;
+    },
+
+    createView: function() {
+        var wd = this.payload['data'];
+        this.dataStore = Ext.create("Reason.store.widgets.GridData");
+        this.dataStore.loadData(wd['gridvals']);
+        this.gridDataView = Ext.widget("griddataviewer", {
+             store: this.dataStore,
+             title: 'Grid Data for ' + this.payload['varname'],
+        });
+
+        examine = {wd:wd, tt:this};
+
+        this.createMyRefs(this.gridDataView.id);
+        Ext.ComponentQuery.query("viewport > #center-panel")[0].add(
+            this.gridDataView);
+    },
+
+    statics: {
+        widgetName: "grid_data",
+        displayName: "Grid Data Viewer",
+        supportsDataObjects: false,
+        supportsParameterFiles: true,
+        preCreation: function(obj) {
+            reason.server.method("create_grid_dataview", {pfname:obj.varname});
+        },
+    },
+});


diff -r 24597a575cf0773ad88932262022f43645f9a7e3 -r 625fdd3d6976fea299c41973b5df075cfd35bcdf yt/gui/reason/html/app/controller/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
@@ -159,14 +159,14 @@
         preCreation: function(obj) {
             var widget = Ext.create(this.getName())
             function makeProj(b, e) {
-                reason.fireEvent("disableinput");
-                yt_rpc.ExtDirectREPL.create_proj({
+                reason.server.method('create_proj',
+                    {
                         pfname: obj.varname,
                         axis: win.query("#axis")[0].getValue(),
                         field: win.query("#field")[0].getValue(),
                         weight: win.query("#weightField")[0].getValue(),
                         onmax: win.query("#maxDens")[0].getValue(),
-                }, function() { examine = arguments; });
+                    });
                 win.destroy();
             }
             var title = widget.templateManager.applyObject(obj, 'pwt');


diff -r 24597a575cf0773ad88932262022f43645f9a7e3 -r 625fdd3d6976fea299c41973b5df075cfd35bcdf yt/gui/reason/html/app/controller/widgets/SampleWidget.js
--- a/yt/gui/reason/html/app/controller/widgets/SampleWidget.js
+++ b/yt/gui/reason/html/app/controller/widgets/SampleWidget.js
@@ -28,16 +28,16 @@
 
     statics: {
         widgetName: 'sample_widget',
-        supportsDataObjects: true,
-        supportsParameterFiles: true,
+        supportsDataObjects: false,
+        supportsParameterFiles: false,
         displayName: 'Sample Widget',
-        factory: function(obj) {
+        preCreation: function(obj) {
             return new this({varname:obj.varname});
         },
     },
 
-    config: {
-        varname: null,
-    },
+    applyPayload: function(payload) {
+        return;
+    }
 
 });


diff -r 24597a575cf0773ad88932262022f43645f9a7e3 -r 625fdd3d6976fea299c41973b5df075cfd35bcdf yt/gui/reason/html/app/store/widgets/GridData.js
--- /dev/null
+++ b/yt/gui/reason/html/app/store/widgets/GridData.js
@@ -0,0 +1,51 @@
+/**********************************************************************
+Grid data store for Reason
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define('Reason.store.widgets.GridData', {
+    extend: 'Ext.data.Store',
+    id: 'griddata',
+    fields: [
+       {name: 'grid_id', type:'int'},
+       {name: 'level', type:'int'},
+       {name: 'left_edge_x', type: 'float'},
+       {name: 'left_edge_y', type: 'float'},
+       {name: 'left_edge_z', type: 'float'},
+       {name: 'right_edge_x', type: 'float'},
+       {name: 'right_edge_y', type: 'float'},
+       {name: 'right_edge_z', type: 'float'},
+       {name: 'dim_x', type: 'int'},
+       {name: 'dim_y', type: 'int'},
+       {name: 'dim_z', type: 'int'},
+       {name: 'cells', type: 'int'},
+    ],
+    data: [],
+});
+


diff -r 24597a575cf0773ad88932262022f43645f9a7e3 -r 625fdd3d6976fea299c41973b5df075cfd35bcdf yt/gui/reason/html/app/view/widgets/GridDataViewer.js
--- /dev/null
+++ b/yt/gui/reason/html/app/view/widgets/GridDataViewer.js
@@ -0,0 +1,111 @@
+/**********************************************************************
+The Grid Data Viewer View
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define("Reason.view.widgets.GridDataViewer", {
+    extend: 'Ext.grid.Panel',
+    title: 'This should not be visible.',
+    alias: 'widget.griddataviewer',
+    iconCls: 'graph',
+    autoScroll: true,
+    width: '100%',
+    height: '100%',
+    closable: true,
+    columns: [
+         {
+             id: 'grid_id',
+             header: 'Grid ID',
+             width: 100,
+             dataIndex: 'grid_id',
+             sortable: true,
+         }, {
+             id: 'left_edge_x',
+             header: 'Left Edge x',
+             width: 100,
+             dataIndex: 'left_edge_x',
+             sortable: true,
+         }, {
+             id: 'left_edge_y',
+             header: 'Left Edge y',
+             width: 100,
+             dataIndex: 'left_edge_y',
+             sortable: true,
+         }, {
+             id: 'left_edge_z',
+             header: 'Left Edge z',
+             width: 100,
+             dataIndex: 'left_edge_z',
+             sortable: true,
+         }, {
+             id: 'right_edge_x',
+             header: 'Right Edge x',
+             width: 100,
+             dataIndex: 'right_edge_x',
+             sortable: true,
+         }, {
+             id: 'right_edge_y',
+             header: 'Right Edge y',
+             width: 100,
+             dataIndex: 'right_edge_y',
+             sortable: true,
+         }, {
+             id: 'right_edge_z',
+             header: 'Right Edge z',
+             width: 100,
+             dataIndex: 'right_edge_z',
+             sortable: true,
+         }, {
+             id: 'dim_x',
+             header: 'DimX',
+             width: 100,
+             dataIndex: 'dim_x',
+             sortable: true,
+         }, {
+             id: 'dim_y',
+             header: 'DimY',
+             width: 100,
+             dataIndex: 'dim_y',
+             sortable: true,
+         }, {
+             id: 'dim_z',
+             header: 'DimZ',
+             width: 100,
+             dataIndex: 'dim_z',
+             sortable: true,
+         }, {
+             id: 'cells',
+             header: 'Cells',
+             width: 100,
+             dataIndex: 'cells',
+             sortable: true,
+         },
+     ],
+});
+



https://bitbucket.org/yt_analysis/yt/changeset/d13e69d688bf/
changeset:   d13e69d688bf
branch:      yt
user:        MatthewTurk
date:        2012-06-05 19:49:38
summary:     Change createView to return a value, instead of adding it to the #center-panel
itself.
affected #:  3 files

diff -r 625fdd3d6976fea299c41973b5df075cfd35bcdf -r d13e69d688bf6dcd45750f68d74d8e7224f97964 yt/gui/reason/html/app/controller/WidgetDirector.js
--- a/yt/gui/reason/html/app/controller/WidgetDirector.js
+++ b/yt/gui/reason/html/app/controller/WidgetDirector.js
@@ -117,7 +117,8 @@
             widgettype: widgetInfo.widgetname,
             widget: newWidget
         });
-        newWidget.createView();
+        Ext.ComponentQuery.query("viewport > #center-panel")[0].add(
+            newWidget.createView());
     },
 
     sendPayload: function(payload) {


diff -r 625fdd3d6976fea299c41973b5df075cfd35bcdf -r d13e69d688bf6dcd45750f68d74d8e7224f97964 yt/gui/reason/html/app/controller/widgets/GridDataViewer.js
--- a/yt/gui/reason/html/app/controller/widgets/GridDataViewer.js
+++ b/yt/gui/reason/html/app/controller/widgets/GridDataViewer.js
@@ -60,8 +60,7 @@
         examine = {wd:wd, tt:this};
 
         this.createMyRefs(this.gridDataView.id);
-        Ext.ComponentQuery.query("viewport > #center-panel")[0].add(
-            this.gridDataView);
+        return this.gridDataView;
     },
 
     statics: {


diff -r 625fdd3d6976fea299c41973b5df075cfd35bcdf -r d13e69d688bf6dcd45750f68d74d8e7224f97964 yt/gui/reason/html/app/controller/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
@@ -147,8 +147,7 @@
         this.getContourField().store = wd['fields'];
         this.getContourField().value = wd['initial_field'];
         this.applyExecuteHandlers(this.plotWindowView);
-        Ext.ComponentQuery.query("viewport > #center-panel")[0].add(
-            this.plotWindowView);
+        return this.plotWindowView;
     },
 
     statics: {



https://bitbucket.org/yt_analysis/yt/changeset/8461ad0b0bfe/
changeset:   8461ad0b0bfe
branch:      yt
user:        MatthewTurk
date:        2012-06-05 19:53:56
summary:     Fix quit function.
affected #:  2 files

diff -r d13e69d688bf6dcd45750f68d74d8e7224f97964 -r 8461ad0b0bfef01a963899974d8181b55a74f6a1 yt/gui/reason/html/app/controller/MenuActions.js
--- a/yt/gui/reason/html/app/controller/MenuActions.js
+++ b/yt/gui/reason/html/app/controller/MenuActions.js
@@ -82,7 +82,7 @@
     },
 
     pastebinScript: function(b, e) {
-        reason.server('paste_session', {}, function(f, a) {
+        reason.server.method('paste_session', {}, function(f, a) {
             if (a.result['status'] == 'SUCCESS') {
                 var alert_text = 'Pasted session to:<br>' + 
                 a.result['site']
@@ -100,7 +100,7 @@
 
     quitReason: function(b, e) {
         this.application.fireEvent("stopheartbeat");
-        reason.server('shutdown', {}, function(f, a) {
+        reason.server.method('shutdown', {}, function(f, a) {
         Ext.Msg.alert("Goodbye!", "Goodbye from Reason!", function() {
         window.open("http://www.google.com/", "_top");});});
     },


diff -r d13e69d688bf6dcd45750f68d74d8e7224f97964 -r 8461ad0b0bfef01a963899974d8181b55a74f6a1 yt/gui/reason/html/app/controller/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
@@ -218,9 +218,7 @@
                         h: controller.getImage().height};
             var code = controller.templateManager.applyObject(
                         args, "recenterImage");
-            yt_rpc.ExtDirectREPL.execute(
-                {code:code, hide:true},
-                Ext.emptyFn);
+            reason.server.execute(code, true);
         });
     },
 });



https://bitbucket.org/yt_analysis/yt/changeset/2617a3e4f0f9/
changeset:   2617a3e4f0f9
branch:      yt
user:        MatthewTurk
date:        2012-06-07 04:04:20
summary:     2D plot creation now more robust, and supports both slices and projections.
affected #:  2 files

diff -r 8461ad0b0bfef01a963899974d8181b55a74f6a1 -r 2617a3e4f0f9569d4a7f201518231b21bbd97841 yt/gui/reason/html/app/controller/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
@@ -154,27 +154,69 @@
         widgetName: 'plot_window',
         supportsDataObjects: false,
         supportsParameterFiles: true,
-        displayName: 'Do not use',
+        displayName: '2D Plot',
         preCreation: function(obj) {
-            var widget = Ext.create(this.getName())
-            function makeProj(b, e) {
-                reason.server.method('create_proj',
-                    {
-                        pfname: obj.varname,
-                        axis: win.query("#axis")[0].getValue(),
-                        field: win.query("#field")[0].getValue(),
-                        weight: win.query("#weightField")[0].getValue(),
-                        onmax: win.query("#maxDens")[0].getValue(),
-                    });
+            var widget = Ext.create(this.getName());
+            function makePlot(b, e) {
+                var conf = {
+                    pfname: obj.varname,
+                    axis: win.query("#axis")[0].getValue(),
+                    field: win.query("#field")[0].getValue(),
+                    onmax: win.query("#maxDens")[0].getValue(),
+                };
+                var method = 'create_slice';
+                if (win.query("#plotType")[0].getValue() == 'Projection') {
+                    method = 'create_proj';
+                    conf['weight'] = win.query("#weightField")[0].getValue();
+                } else {
+                  conf['center'] = [win.query("#slice_x_center")[0].getValue(),
+                                    win.query("#slice_y_center")[0].getValue(),
+                                    win.query("#slice_z_center")[0].getValue()];
+                }
+                reason.server.method(method, conf);
                 win.destroy();
             }
+            function togglePlotType(b, e) {
+                var plotType = win.query("#plotType")[0].getValue();
+                examine = win;
+                if (plotType == 'Projection') {
+                    win.query("#weightField")[0].enable();
+                    win.query("#maxDens")[0].disable();
+                    win.query("#slice_x_center")[0].disable();
+                    win.query("#slice_y_center")[0].disable();
+                    win.query("#slice_z_center")[0].disable();
+                } else {
+                    win.query("#weightField")[0].disable();
+                    win.query("#maxDens")[0].enable();
+                    win.query("#slice_x_center")[0].enable();
+                    win.query("#slice_y_center")[0].enable();
+                    win.query("#slice_z_center")[0].enable();
+                }
+            }
+            function toggleMaxDens(checkbox, checked) {
+                var plotType = win.query("#plotType")[0].getValue();
+                if (plotType == "Projection") { return; }
+                if (checked == true) {
+                    win.query("#slice_x_center")[0].disable();
+                    win.query("#slice_y_center")[0].disable();
+                    win.query("#slice_z_center")[0].disable();
+                } else {
+                    win.query("#slice_x_center")[0].enable();
+                    win.query("#slice_y_center")[0].enable();
+                    win.query("#slice_z_center")[0].enable();
+                }
+            }
             var title = widget.templateManager.applyObject(obj, 'pwt');
             win = Ext.widget("plotwindowcreator", {title:title, obj:obj});
             win.query("#weightField")[0].store = 
                 ['None'].concat(obj.field_list);
             win.query("#field")[0].store = obj.field_list;
-            win.query("#create")[0].on('click', makeProj);
-            win.query("#cancel")[0].on('click', function(){win.destroy;});
+            win.query("#create")[0].on('click', makePlot);
+            win.query("#cancel")[0].on('click', function(){win.destroy();});
+            win.query("#maxDens")[0].on('change', toggleMaxDens);
+            win.query("#plotType")[0].on('change', togglePlotType);
+            togglePlotType();
+            toggleMaxDens();
             win.show();
             /* Note that in this case, our instance of 'widget', which is this
                class, is not long-lived.  It dies after the window is


diff -r 8461ad0b0bfef01a963899974d8181b55a74f6a1 -r 2617a3e4f0f9569d4a7f201518231b21bbd97841 yt/gui/reason/html/app/view/widgets/PlotWindowCreator.js
--- a/yt/gui/reason/html/app/view/widgets/PlotWindowCreator.js
+++ b/yt/gui/reason/html/app/view/widgets/PlotWindowCreator.js
@@ -32,51 +32,89 @@
 Ext.define("Reason.view.widgets.PlotWindowCreator", {
     extend: 'Ext.window.Window',
     alias: 'widget.plotwindowcreator',
-    layout: 'fit',
-    width: 370,
-    height: 220,
+    width: 480,
+    height: 200,
     modal: true,
-    resizable: false,
+    resizable: true,
     draggable: false,
     border: false,
+    layout: 'fit',
     title: "You shouldn't see this.",
 
     items: [{ xtype: 'form',
               labelWidth:80,
               frame:true,
+              defaults: {
+                  bodyStyle:'padding:15px 20px'
+              },
+              layout: {
+                  type: 'table',
+                  columns: 2
+              },
               items: [{
                   xtype:'combo',
+                  fieldLabel: 'Type of Plot',
+                  itemId: 'plotType',
+                  store: ['Slice', 'Projection'],
+                  width: 200,
+                  allowBlank: false,
+                  editable: false,
+                  value: 'Slice'
+              },{
+                  xtype:'checkbox',
+                  fieldLabel: 'Center on Max',
+                  itemId: 'maxDens',
+                  width: 200,
+                  allowBlank:false,
+              },{
+                  xtype:'combo',
                   fieldLabel: 'Axis',
                   itemId: 'axis',
                   store:['X','Y','Z'],
-                  width: 230,
-                  allowBlank:false,
+                  width: 200,
+                  allowBlank: false,
+                  editable: false,
                   triggerAction: 'all',
                   value: 'X',
               },{
-                  xtype:'checkbox',
-                  fieldLabel: 'Center on Max',
-                  itemId: 'maxDens',
-                  width: 90,
+                  xtype:'textfield',
+                  fieldLabel: 'Center X',
+                  itemId: 'slice_x_center',
+                  value: '0.5',
+                  width: 200,
                   allowBlank:false,
               },{
                   xtype:'combo',
                   fieldLabel: 'Field',
                   itemId: 'field',
                   store: [],
-                  width: 230,
+                  width: 200,
                   allowBlank:false,
                   triggerAction: 'all',
                   value: 'Density'
               },{
+                  xtype:'textfield',
+                  fieldLabel: 'Center Y',
+                  itemId: 'slice_y_center',
+                  value: '0.5',
+                  width: 200,
+                  allowBlank:false,
+              },{
                   xtype:'combo',
                   fieldLabel: 'Weight Field',
                   itemId: 'weightField',
                   store: ['None'],
-                  width: 230,
+                  width: 200,
                   allowBlank:false,
                   triggerAction: 'all',
                   value: 'None'
+              },{
+                  xtype:'textfield',
+                  fieldLabel: 'Center Z',
+                  itemId: 'slice_z_center',
+                  value: '0.5',
+                  width: 200,
+                  allowBlank:false,
               }],
               buttons: [
                   {



https://bitbucket.org/yt_analysis/yt/changeset/f3036443bd5c/
changeset:   f3036443bd5c
branch:      yt
user:        MatthewTurk
date:        2012-06-08 03:10:35
summary:     Calling refresh() on plot windows to ensure an image is there.  Still needs a
"Loading..." image.
affected #:  2 files

diff -r 2617a3e4f0f9569d4a7f201518231b21bbd97841 -r f3036443bd5cbdd936a8f66fb95421f32f1837c2 yt/gui/reason/html/app/controller/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
@@ -36,6 +36,7 @@
     templates: {
         pwt: 'Projection Details for {name}',
         swt: 'Slice Details for {name}',
+        refresh: '{widget.varname}.refresh()',
         scrollZoom: '{widget.varname}.scroll_zoom({a1})',
         fieldChange: '{widget.varname}.set_current_field("{a1.data[\'field1\']}")',
         singleUpArrow:    '{widget.varname}.pan_rel(( 0.0, -0.1))',
@@ -140,6 +141,9 @@
             title: wd['title'],
         });
         var newRefs = this.createMyRefs(this.plotWindowView.id);
+        var refresh = this.templateManager.applyObject(
+            {widget: this.plotWindowView}, 'refresh');
+        reason.server.execute(refresh, false);
         this.getColorbar().src = "data:image/png;base64," + wd['colorbar'];
         this.getFieldSelector().store = wd['fields'];
         this.getFieldSelector().value = wd['initial_field'];


diff -r 2617a3e4f0f9569d4a7f201518231b21bbd97841 -r f3036443bd5cbdd936a8f66fb95421f32f1837c2 yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -278,6 +278,10 @@
     def set_vector_info(self, skip, scale = 1):
         self._vector_info = (skip, scale)
 
+    @invalidate_data
+    def refresh(self):
+        self._setup_plots()
+
 class PWViewer(PlotWindow):
     """A viewer for PlotWindows.
 



https://bitbucket.org/yt_analysis/yt/changeset/8e21fdf72d2a/
changeset:   8e21fdf72d2a
branch:      yt
user:        MatthewTurk
date:        2012-06-12 20:18:23
summary:     Two things:

 * Moving to a widget_store object, which will hide all the execution of widget
   creation.  This will look much nicer and will be easier to manage.
 * Adding a parameter file widget.  First pass shows statistics for mesh
   information.
affected #:  10 files

diff -r f3036443bd5cbdd936a8f66fb95421f32f1837c2 -r 8e21fdf72d2aafb9e2540a9f8728ca344bde178c yt/gui/reason/bottle_mods.py
--- a/yt/gui/reason/bottle_mods.py
+++ b/yt/gui/reason/bottle_mods.py
@@ -95,6 +95,11 @@
     def replay_payloads(self):
         return self.recorded_payloads
 
+    def widget_payload(self, widget, data):
+        data['type'] = 'widget_payload'
+        data['widget_id'] = widget._ext_widget_id
+        self.add_payload(data)
+
 
 class YTRocketServer(ServerAdapter):
     server_info = {} # Hack to get back at instance vars
@@ -206,3 +211,30 @@
     server = server_type(host='localhost', port=port, **kwargs)
     mylog.info("Starting up the server.")
     run(server=server)
+
+class MethodLock(object):
+    _shared_state = {}
+    locks = None
+
+    def __new__(cls, *p, **k):
+        self = object.__new__(cls, *p, **k)
+        self.__dict__ = cls._shared_state
+        return self
+
+    def __init__(self):
+        if self.locks is None: self.locks = {}
+
+    def __call__(self, func):
+        if str(func) not in self.locks:
+            self.locks[str(func)] = threading.Lock()
+        @wraps(func)
+        def locker(*args, **kwargs):
+            print "Acquiring lock on %s" % (str(func))
+            with self.locks[str(func)]:
+                rv = func(*args, **kwargs)
+            print "Regained lock on %s" % (str(func))
+            return rv
+        return locker
+
+lockit = MethodLock()
+


diff -r f3036443bd5cbdd936a8f66fb95421f32f1837c2 -r 8e21fdf72d2aafb9e2540a9f8728ca344bde178c yt/gui/reason/extdirect_repl.py
--- a/yt/gui/reason/extdirect_repl.py
+++ b/yt/gui/reason/extdirect_repl.py
@@ -48,9 +48,10 @@
 from yt.utilities.definitions import inv_axis_names
 from yt.visualization.image_writer import apply_colormap
 from yt.visualization.api import Streamlines
+from .widget_store import WidgetStore
 
 from .bottle_mods import preroute, BottleDirectRouter, notify_route, \
-                         PayloadHandler
+                         PayloadHandler, lockit
 from yt.utilities.bottle import response, request, route, static_file
 from .basic_repl import ProgrammaticREPL
 
@@ -73,32 +74,6 @@
 
 local_dir = os.path.dirname(__file__)
 
-class MethodLock(object):
-    _shared_state = {}
-    locks = None
-
-    def __new__(cls, *p, **k):
-        self = object.__new__(cls, *p, **k)
-        self.__dict__ = cls._shared_state
-        return self
-
-    def __init__(self):
-        if self.locks is None: self.locks = {}
-
-    def __call__(self, func):
-        if str(func) not in self.locks:
-            self.locks[str(func)] = threading.Lock()
-        @wraps(func)
-        def locker(*args, **kwargs):
-            print "Acquiring lock on %s" % (str(func))
-            with self.locks[str(func)]:
-                rv = func(*args, **kwargs)
-            print "Regained lock on %s" % (str(func))
-            return rv
-        return locker
-
-lockit = MethodLock()
-
 class ExecutionThread(threading.Thread):
     def __init__(self, repl):
         self.repl = repl
@@ -231,6 +206,8 @@
         self.executed_cell_texts = []
         self.payload_handler = PayloadHandler()
         self.execution_thread = ExecutionThread(self)
+        # We pass in a reference to ourself
+        self.widget_store = WidgetStore(self)
         # Now we load up all the yt.mods stuff, but only after we've finished
         # setting up.
         reason_pylab()
@@ -239,6 +216,7 @@
         self.execute("data_objects = []", hide = True)
         self.locals['load_script'] = ext_load_script
         self.locals['deliver_image'] = deliver_image
+        self.locals['widget_store'] = self.widget_store
 
     def activate(self):
         self._setup_logging_handlers()
@@ -413,27 +391,6 @@
         response.headers["content-disposition"] = "attachment;"
         return cs
 
-    def _add_widget(self, widget_name, widget_data_name = None):
-        # We need to make sure that we aren't running in advance of a new
-        # object being added.
-        self.execution_thread.queue.join()
-        widget = self.locals[widget_name]
-        uu = str(uuid.uuid1()).replace("-","_")
-        varname = "%s_%s" % (widget._widget_name, uu)
-        widget._ext_widget_id = varname
-        # THIS BREAKS THE SCRIPT DOWNLOAD!
-        # We need to make the variable be bound via an execution mechanism
-        command = "%s = %s\n" % (varname, widget_name)
-        payload = {'type': 'widget',
-                   'widget_type': widget._widget_name,
-                   'varname': varname,
-                   'data': None}
-        widget._ext_widget_id = varname
-        if widget_data_name is not None:
-            payload['data'] = self.locals[widget_data_name]
-        self.payload_handler.add_payload(payload)
-        return command
-
     @lockit
     def load(self, base_dir, filename):
         pp = os.path.join(base_dir, filename)
@@ -489,45 +446,6 @@
                                          'widget_data_name': '_twidget_data'})
 
     @lockit
-    def create_proj(self, pfname, axis, field, weight, onmax):
-        if weight == "None": weight = None
-        else: weight = "'%s'" % (weight)
-        if not onmax:
-            center_string = None
-        else:
-            center_string = "_tpf.h.find_max('Density')[1]"
-        funccall = """
-        _tpf = %(pfname)s
-        _taxis = %(axis)s
-        _tfield = "%(field)s"
-        _tweight = %(weight)s
-        _tcen = %(center_string)s
-        _tsl = _tpf.h.proj(_taxis,_tfield, weight_field=_tweight, periodic = True, center=_tcen)
-        _txax, _tyax = x_dict[_taxis], y_dict[_taxis]
-        DLE, DRE = _tpf.domain_left_edge, _tpf.domain_right_edge
-        from yt.visualization.plot_window import PWViewerExtJS
-        _tpw = PWViewerExtJS(_tsl, (DLE[_txax], DRE[_txax], DLE[_tyax], DRE[_tyax]), setup = False)
-        _tpw.set_current_field("%(field)s")
-        _tfield_list = list(set(_tpf.h.field_list + _tpf.h.derived_field_list))
-        _tfield_list.sort()
-        _tcb = _tpw._get_cbar_image()
-        _twidget_data = {'fields': _tfield_list,
-                         'initial_field': _tfield,
-                         'title': "%%s Projection" %% (_tpf),
-                         'colorbar': _tcb}
-        """ % dict(pfname = pfname,
-                   axis = inv_axis_names[axis],
-                   weight = weight,
-                   center_string = center_string,
-                   field=field)
-        # There is a call to do this, but I have forgotten it ...
-        funccall = "\n".join((line.strip() for line in funccall.splitlines()))
-        self.execute(funccall, hide = True)
-        self.execution_thread.queue.put({'type': 'add_widget',
-                                         'name': '_tpw',
-                                         'widget_data_name': '_twidget_data'})
-
-    @lockit
     def create_mapview(self, widget_name):
         # We want multiple maps simultaneously
         uu = "/%s/%s" % (getattr(self, "_global_token", ""),
@@ -616,40 +534,6 @@
 
 
     @lockit
-    def create_grid_dataview(self, pfname):
-        funccall = """
-        _tpf = %(pfname)s
-        """ % dict(pfname = pfname)
-        funccall = "\n".join((line.strip() for line in funccall.splitlines()))
-        self.execute(funccall, hide = True)
-        self.execution_thread.queue.join()
-        pf = self.locals['_tpf']
-        levels = pf.h.grid_levels
-        left_edge = pf.h.grid_left_edge
-        right_edge = pf.h.grid_right_edge
-        dimensions = pf.h.grid_dimensions
-        cell_counts = pf.h.grid_dimensions.prod(axis=1)
-        # This is annoying, and not ... that happy for memory.
-        i = pf.h.grids[0]._id_offset
-        vals = []
-        for i, (L, LE, RE, dim, cell) in enumerate(zip(
-            levels, left_edge, right_edge, dimensions, cell_counts)):
-            vals.append([ int(i), int(L[0]),
-                          float(LE[0]), float(LE[1]), float(LE[2]),
-                          float(RE[0]), float(RE[1]), float(RE[2]),
-                          int(dim[0]), int(dim[1]), int(dim[2]),
-                          int(cell)] )
-        uu = str(uuid.uuid1()).replace("-","_")
-        varname = "gg_%s" % (uu)
-        payload = {'type': 'widget',
-                   'widget_type': 'grid_data',
-                   'varname': varname, # Is just "None"
-                   'data': dict(gridvals = vals),
-                   }
-        self.execute("%s = None\n" % (varname), hide=True)
-        self.payload_handler.add_payload(payload)
-
-    @lockit
     def create_grid_viewer(self, pfname):
         funccall = """
         _tpf = %(pfname)s


diff -r f3036443bd5cbdd936a8f66fb95421f32f1837c2 -r 8e21fdf72d2aafb9e2540a9f8728ca344bde178c yt/gui/reason/html/app/controller/WidgetDirector.js
--- a/yt/gui/reason/html/app/controller/WidgetDirector.js
+++ b/yt/gui/reason/html/app/controller/WidgetDirector.js
@@ -29,6 +29,7 @@
                "Reason.controller.widgets.PlotWindow",
                "Reason.controller.widgets.ProgressBar",
                "Reason.controller.widgets.GridDataViewer",
+               "Reason.controller.widgets.ParameterFile",
     ],
     stores: ['WidgetTypes', 'WidgetInstances'],
     views: ['WidgetTypesGrid', 'WidgetInstancesGrid'],


diff -r f3036443bd5cbdd936a8f66fb95421f32f1837c2 -r 8e21fdf72d2aafb9e2540a9f8728ca344bde178c yt/gui/reason/html/app/controller/widgets/GridDataViewer.js
--- a/yt/gui/reason/html/app/controller/widgets/GridDataViewer.js
+++ b/yt/gui/reason/html/app/controller/widgets/GridDataViewer.js
@@ -30,6 +30,7 @@
 
     templates: {
         title: "Grid Data for {widget.varname}",
+        createGridViewer: 'widget_store.create_grid_dataview({varname})',
     },
 
     widgetTriggers: [
@@ -41,7 +42,6 @@
     ],
 
     viewRefs: [
-
     ],
 
     applyPayload: function(payload) {
@@ -57,8 +57,6 @@
              title: 'Grid Data for ' + this.payload['varname'],
         });
 
-        examine = {wd:wd, tt:this};
-
         this.createMyRefs(this.gridDataView.id);
         return this.gridDataView;
     },
@@ -69,7 +67,10 @@
         supportsDataObjects: false,
         supportsParameterFiles: true,
         preCreation: function(obj) {
-            reason.server.method("create_grid_dataview", {pfname:obj.varname});
+            var widget = Ext.create(this.getName());
+            var cmd = widget.templateManager.applyObject(
+                obj, 'createGridViewer');
+            reason.server.execute(cmd);
         },
     },
 });


diff -r f3036443bd5cbdd936a8f66fb95421f32f1837c2 -r 8e21fdf72d2aafb9e2540a9f8728ca344bde178c yt/gui/reason/html/app/controller/widgets/ParameterFile.js
--- /dev/null
+++ b/yt/gui/reason/html/app/controller/widgets/ParameterFile.js
@@ -0,0 +1,89 @@
+/**********************************************************************
+The Parameter File widget
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define("Reason.controller.widgets.ParameterFile", {
+    extend: 'Reason.controller.widgets.BaseWidget',
+    requires: ['Reason.view.widgets.ParameterFileDisplay',
+               'Reason.view.widgets.LevelStats',
+               'Reason.store.widgets.LevelInformation'],
+    templates: {
+        title: "Dataset: {widget.varname}",
+        createDisplay: 'widget_store.create_pf_display({varname})',
+        getLevelInfo: 'widget_store["{widget.varname}"].deliver_level_stats()',
+        getFieldInfo: 'widget_store["{widget.varname}"].deliver_fields()',
+    },
+
+    widgetTriggers: [
+    ],
+
+    executionTriggers: [
+    ],
+
+    viewRefs: [
+        { ref:'levelStats', selector: '#levelStats'},
+        { ref:'statsPanel', selector: '#statsPanel'},
+    ],
+
+    applyPayload: function(payload) {
+    },
+
+    createView: function() {
+        var wd = this.payload['data'];
+        examine = wd;
+        this.levelDataStore = Ext.create("Reason.store.widgets.LevelInformation");
+        this.levelDataStore.loadData(wd['level_stats']);
+        this.levelStatsDisplay = Ext.widget("levelstats", {
+            store: this.levelDataStore,
+        });
+        examine = this.levelStatsDisplay;
+        this.dataView = Ext.widget("pfdisplay", {
+             title: 'Data for ' + this.payload['varname'],
+        });
+        this.dataView.query("#statsPanel")[0].add(this.levelStatsDisplay);
+        this.createMyRefs(this.dataView.id);
+        return this.dataView;
+    },
+
+    statics: {
+        widgetName: 'parameterfile',
+        supportsDataObjects: false,
+        supportsParameterFiles: true,
+        displayName: 'Dataset Information',
+        preCreation: function(obj) {
+            var widget = Ext.create(this.getName());
+            var cmd = widget.templateManager.applyObject(
+                obj, 'createDisplay');
+            reason.server.execute(cmd);
+        },
+
+    },
+
+});


diff -r f3036443bd5cbdd936a8f66fb95421f32f1837c2 -r 8e21fdf72d2aafb9e2540a9f8728ca344bde178c yt/gui/reason/html/app/controller/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
@@ -36,36 +36,40 @@
     templates: {
         pwt: 'Projection Details for {name}',
         swt: 'Slice Details for {name}',
-        refresh: '{widget.varname}.refresh()',
-        scrollZoom: '{widget.varname}.scroll_zoom({a1})',
-        fieldChange: '{widget.varname}.set_current_field("{a1.data[\'field1\']}")',
-        singleUpArrow:    '{widget.varname}.pan_rel(( 0.0, -0.1))',
-        singleRightArrow: '{widget.varname}.pan_rel(( 0.1,  0.0))',
-        singleDownArrow:  '{widget.varname}.pan_rel(( 0.0   0.1))',
-        singleLeftArrow:  '{widget.varname}.pan_rel((-0.1,  0.0))',
-        doubleUpArrow:    '{widget.varname}.pan_rel(( 0.0, -0.5))',
-        doubleRightArrow: '{widget.varname}.pan_rel(( 0.5,  0.0))',
-        doubleDownArrow:  '{widget.varname}.pan_rel(( 0.0   0.5))',
-        doubleLeftArrow:  '{widget.varname}.pan_rel((-0.5,  0.0))',
-        zoomIn10x:  '{widget.varname}.zoom(10.0)',
-        zoomIn2x:   '{widget.varname}.zoom( 2.0)',
-        zoomOut10x: '{widget.varname}.zoom( 0.1)',
-        zoomOut2x:  '{widget.varname}.zoom( 0.5)',
-        adjustTransform: '{widget.varname}.set_transform(' +
-                         '{widget.varname}._current_field, ' +
+        refresh: 'widget_store["{widget.varname}"].refresh()',
+        createSlice: 'widget_store.create_slice({pfname}, [{center}], "{axis}",' + 
+                     '"{field}", {onmax:capitalize})',
+        createProj: 'widget_store.create_proj({pfname}, "{axis}",' + 
+                     '"{field}", "{weight}")',
+        scrollZoom: 'widget_store["{widget.varname}"].scroll_zoom({a1})',
+        fieldChange: 'widget_store["{widget.varname}"].set_current_field("{a1.data[\'field1\']}")',
+        singleUpArrow:    'widget_store["{widget.varname}"].pan_rel(( 0.0, -0.1))',
+        singleRightArrow: 'widget_store["{widget.varname}"].pan_rel(( 0.1,  0.0))',
+        singleDownArrow:  'widget_store["{widget.varname}"].pan_rel(( 0.0   0.1))',
+        singleLeftArrow:  'widget_store["{widget.varname}"].pan_rel((-0.1,  0.0))',
+        doubleUpArrow:    'widget_store["{widget.varname}"].pan_rel(( 0.0, -0.5))',
+        doubleRightArrow: 'widget_store["{widget.varname}"].pan_rel(( 0.5,  0.0))',
+        doubleDownArrow:  'widget_store["{widget.varname}"].pan_rel(( 0.0   0.5))',
+        doubleLeftArrow:  'widget_store["{widget.varname}"].pan_rel((-0.5,  0.0))',
+        zoomIn10x:  'widget_store["{widget.varname}"].zoom(10.0)',
+        zoomIn2x:   'widget_store["{widget.varname}"].zoom( 2.0)',
+        zoomOut10x: 'widget_store["{widget.varname}"].zoom( 0.1)',
+        zoomOut2x:  'widget_store["{widget.varname}"].zoom( 0.5)',
+        adjustTransform: 'widget_store["{widget.varname}"].set_transform(' +
+                         'widget_store["{widget.varname}"]._current_field, ' +
                          '"{a1.data[\'field1\']}")',
-        adjustColormap:  '{widget.varname}.set_cmap(' +
-                         '{widget.varname}._current_field, ' +
+        adjustColormap:  'widget_store["{widget.varname}"].set_cmap(' +
+                         'widget_store["{widget.varname}"]._current_field, ' +
                          '"{a1.data[\'field1\']}")',
-        adjustContours:  '{widget.varname}.set_contour_info(' +
+        adjustContours:  'widget_store["{widget.varname}"].set_contour_info(' +
                          '"{[control.getContourField().getValue()]}",' +
                          ' {[control.getNcont().getValue()]},' +
                          ' {[control.getLogit().getValue()]:capitalize})',
-        adjustVectors:   '{widget.varname}.set_vector_info(' +
+        adjustVectors:   'widget_store["{widget.varname}"].set_vector_info(' +
                          '{[control.getVectorSkip()]})',
-        recenterImage:   '{widget.varname}.image_recenter(' +
+        recenterImage:   'widget_store["{widget.varname}"].image_recenter(' +
                          '{x}, {y}, {w}, {h})',
-        dragImage:       '{widget.varname}.pan_rel(({rel_x}, {rel_y}))',
+        dragImage:       'widget_store["{widget.varname}"].pan_rel(({rel_x}, {rel_y}))',
     },
 
     widgetTriggers: [
@@ -166,18 +170,19 @@
                     pfname: obj.varname,
                     axis: win.query("#axis")[0].getValue(),
                     field: win.query("#field")[0].getValue(),
-                    onmax: win.query("#maxDens")[0].getValue(),
+                    onmax: "" + win.query("#maxDens")[0].getValue(),
                 };
-                var method = 'create_slice';
+                var method = 'createSlice';
                 if (win.query("#plotType")[0].getValue() == 'Projection') {
-                    method = 'create_proj';
+                    method = 'createProj';
                     conf['weight'] = win.query("#weightField")[0].getValue();
                 } else {
                   conf['center'] = [win.query("#slice_x_center")[0].getValue(),
                                     win.query("#slice_y_center")[0].getValue(),
                                     win.query("#slice_z_center")[0].getValue()];
                 }
-                reason.server.method(method, conf);
+                var cmd = widget.templateManager.applyObject(conf, method);
+                reason.server.execute(cmd);
                 win.destroy();
             }
             function togglePlotType(b, e) {


diff -r f3036443bd5cbdd936a8f66fb95421f32f1837c2 -r 8e21fdf72d2aafb9e2540a9f8728ca344bde178c yt/gui/reason/html/app/store/widgets/LevelInformation.js
--- /dev/null
+++ b/yt/gui/reason/html/app/store/widgets/LevelInformation.js
@@ -0,0 +1,44 @@
+/**********************************************************************
+Level Info store for Reason
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define('Reason.store.widgets.LevelInformation', {
+    extend: 'Ext.data.Store',
+    id: 'leveldata',
+    fields: [
+       {name: 'level', type:'int'},
+       {name: 'cell_count', type: 'int'},
+       {name: 'grid_count', type: 'int'},
+       {name: 'grid_rel', type: 'float'},
+       {name: 'cell_rel', type: 'float'},
+    ],
+    data: [],
+});
+


diff -r f3036443bd5cbdd936a8f66fb95421f32f1837c2 -r 8e21fdf72d2aafb9e2540a9f8728ca344bde178c yt/gui/reason/html/app/view/widgets/LevelStats.js
--- /dev/null
+++ b/yt/gui/reason/html/app/view/widgets/LevelStats.js
@@ -0,0 +1,76 @@
+/**********************************************************************
+Level display stats
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define("Reason.view.widgets.LevelStats", {
+    extend: 'Ext.chart.Chart',
+    title: 'Level Stats',
+    alias: 'widget.levelstats',
+    layout: 'absolute',
+    flex: 1.0,
+    itemId: 'levelStats',
+    animate: true,
+    legend: {
+       position: 'right',
+    },
+    axes: [ {
+        type: 'Numeric',
+        position: 'bottom',
+        fields: ['grid_rel', 'cell_rel'],
+        minimum: 0.0,
+        grid: true,
+        title: 'Relative Portion of Mesh',
+        roundToDecimal: function(v) { console.log(v); return(v); },
+    }, {
+        type: 'Category',
+        position: 'left',
+        fields: ['level'],
+        title: 'Level',
+    } ],
+    series: [{
+       type: 'bar',
+       axis: 'bottom',
+       highlight: true,
+       xField: 'level',
+       yField: ['grid_rel', 'cell_rel'],
+       title: ['Level by Grid Count', 'Level by Cell Count'],
+       tips: {
+         trackMouse: true,
+         width: 140,
+         height: 64,
+         renderer: function(storeItem, item) {
+           this.setTitle('Level ' + storeItem.get('level') + ': ' +
+                          storeItem.get('grid_count') + ' grids and ' +
+                          storeItem.get('cell_count') + ' cells.');
+         },
+       },
+       animate: true,
+    }],
+});


diff -r f3036443bd5cbdd936a8f66fb95421f32f1837c2 -r 8e21fdf72d2aafb9e2540a9f8728ca344bde178c yt/gui/reason/html/app/view/widgets/ParameterFileDisplay.js
--- /dev/null
+++ b/yt/gui/reason/html/app/view/widgets/ParameterFileDisplay.js
@@ -0,0 +1,57 @@
+/**********************************************************************
+The Parameter File Display Widget
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define("Reason.view.widgets.ParameterFileDisplay", {
+    extend: 'Ext.tab.Panel',
+    title: 'This should not be visible.',
+    alias: 'widget.pfdisplay',
+    iconCls: 'graph',
+    autoScroll: true,
+    layout: 'absolute',
+    width: '100%',
+    height: '100%',
+    closable: true,
+    activeTab: 0,
+
+    items: [
+        { xtype: 'panel',
+          itemId: 'statsPanel',
+          title: 'Mesh Statistics',
+          layout: {
+            type: 'hbox',
+            pack: 'start',
+            align: 'stretch',
+          },
+          items: []
+        }
+    ],
+});
+


diff -r f3036443bd5cbdd936a8f66fb95421f32f1837c2 -r 8e21fdf72d2aafb9e2540a9f8728ca344bde178c yt/gui/reason/widget_store.py
--- /dev/null
+++ b/yt/gui/reason/widget_store.py
@@ -0,0 +1,157 @@
+"""
+This is a place to store widgets, and to create them.
+
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+"""
+
+from yt.mods import *
+import weakref
+from .bottle_mods import PayloadHandler, lockit
+from yt.visualization.plot_window import PWViewerExtJS
+import uuid
+
+class WidgetStore(dict):
+    def __init__(self, repl):
+        self.repl = weakref.proxy(repl)
+        self.payload_handler = PayloadHandler()
+        super(WidgetStore, self).__init__()
+
+    def _add_widget(self, widget, widget_data = None):
+        # We need to make sure that we aren't running in advance of a new
+        # object being added.
+        #uu = str(uuid.uuid1()).replace("-","_")
+        #varname = "%s_%s" % (widget._widget_name, uu)
+        varname = "%s_%s" % (widget._widget_name, len(self))
+        widget._ext_widget_id = varname
+        payload = {'type': 'widget',
+                   'widget_type': widget._widget_name,
+                   'varname': varname}
+        widget._ext_widget_id = varname
+        payload['data'] = widget_data
+        self[varname] = widget
+        print "DELIVERING", payload
+        self.payload_handler.add_payload(payload)
+
+    @lockit
+    def create_slice(self, pf, center, axis, field, onmax):
+        if onmax: 
+            center = pf.h.find_max('Density')[1]
+        else:
+            center = na.array(center)
+        axis = inv_axis_names[axis.lower()]
+        coord = center[axis]
+        sl = pf.h.slice(axis, coord, center = center, periodic = True)
+        xax, yax = x_dict[axis], y_dict[axis]
+        DLE, DRE = pf.domain_left_edge, pf.domain_right_edge
+        pw = PWViewerExtJS(sl, (DLE[xax], DRE[xax], DLE[yax], DRE[yax]), setup = False)
+        pw.set_current_field(field)
+        field_list = list(set(pf.h.field_list + pf.h.derived_field_list))
+        field_list.sort()
+        cb = pw._get_cbar_image()
+        trans = pw._field_transform[pw._current_field].name
+        widget_data = {'fields': field_list,
+                         'initial_field': field,
+                         'title': "%s Slice" % (pf),
+                         'colorbar': cb,
+                         'initial_transform' : trans}
+        self._add_widget(pw, widget_data)
+
+    @lockit
+    def create_proj(self, pf, axis, field, weight):
+        if weight == "None": weight = None
+        axis = inv_axis_names[axis.lower()]
+        proj = pf.h.proj(axis,field, weight_field=weight, periodic = True)
+        xax, yax = x_dict[axis], y_dict[axis]
+        DLE, DRE = pf.domain_left_edge, pf.domain_right_edge
+        pw = PWViewerExtJS(proj, (DLE[xax], DRE[xax], DLE[yax], DRE[yax]),
+                           setup = False)
+        pw.set_current_field(field)
+        field_list = list(set(pf.h.field_list + pf.h.derived_field_list))
+        field_list.sort()
+        cb = pw._get_cbar_image()
+        widget_data = {'fields': field_list,
+                       'initial_field': field,
+                       'title': "%s Projection" % (pf),
+                       'colorbar': cb}
+        self._add_widget(pw, widget_data)
+
+    @lockit
+    def create_grid_dataview(self, pf):
+        levels = pf.h.grid_levels
+        left_edge = pf.h.grid_left_edge
+        right_edge = pf.h.grid_right_edge
+        dimensions = pf.h.grid_dimensions
+        cell_counts = pf.h.grid_dimensions.prod(axis=1)
+        # This is annoying, and not ... that happy for memory.
+        i = pf.h.grids[0]._id_offset
+        vals = []
+        for i, (L, LE, RE, dim, cell) in enumerate(zip(
+            levels, left_edge, right_edge, dimensions, cell_counts)):
+            vals.append([ int(i), int(L[0]),
+                          float(LE[0]), float(LE[1]), float(LE[2]),
+                          float(RE[0]), float(RE[1]), float(RE[2]),
+                          int(dim[0]), int(dim[1]), int(dim[2]),
+                          int(cell)] )
+        varname = "gg_%s" % (len(self))
+        self[varname] = None
+        payload = {'type': 'widget',
+                   'widget_type': 'grid_data',
+                   'varname': varname, # Is just "None"
+                   'data': dict(gridvals = vals),
+                   }
+        self.payload_handler.add_payload(payload)
+
+    @lockit
+    def create_pf_display(self, pf):
+        widget = ParameterFileWidget(pf)
+        widget_data = {'fields': widget._field_list(),
+                       'level_stats': widget._level_stats(),
+                      }
+        self._add_widget(widget, widget_data)
+
+class ParameterFileWidget(object):
+    _ext_widget_id = None
+    _widget_name = "parameterfile"
+
+    def __init__(self, pf):
+        self.pf = weakref.proxy(pf)
+
+    def _field_list(self):
+        field_list = list(set(self.pf.h.field_list
+                            + self.pf.h.derived_field_list))
+        field_list.sort()
+        return field_list
+
+    def _level_stats(self):
+        level_data = []
+        level_stats = self.pf.h.level_stats
+        ngrids = float(level_stats['numgrids'].sum())
+        ncells = float(level_stats['numcells'].sum())
+        for level in range(self.pf.h.max_level + 1):
+            cell_count = level_stats['numcells'][level]
+            grid_count = level_stats['numgrids'][level]
+            level_data.append({'level' : level,
+                               'cell_count': int(cell_count),
+                               'grid_count': int(grid_count),
+                               'cell_rel': int(100*cell_count/ncells),
+                               'grid_rel': int(100*grid_count/ngrids)})
+        return level_data



https://bitbucket.org/yt_analysis/yt/changeset/a335d4010400/
changeset:   a335d4010400
branch:      yt
user:        MatthewTurk
date:        2012-06-12 23:33:34
summary:     Fixing an issue with selecting fields.  Adding a field display; fields can be
selected and the source for that function pulled back into the browser.
Removed locking of widget creation, as it is unnecessary.
affected #:  9 files

diff -r 8e21fdf72d2aafb9e2540a9f8728ca344bde178c -r a335d40104009b890f57cfb0d3aa7d9cb4eaca7f yt/gui/reason/bottle_mods.py
--- a/yt/gui/reason/bottle_mods.py
+++ b/yt/gui/reason/bottle_mods.py
@@ -100,7 +100,6 @@
         data['widget_id'] = widget._ext_widget_id
         self.add_payload(data)
 
-
 class YTRocketServer(ServerAdapter):
     server_info = {} # Hack to get back at instance vars
     def run(self, handler):


diff -r 8e21fdf72d2aafb9e2540a9f8728ca344bde178c -r a335d40104009b890f57cfb0d3aa7d9cb4eaca7f yt/gui/reason/html/app/controller/widgets/BaseWidget.js
--- a/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
+++ b/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
@@ -49,11 +49,13 @@
         var control = this;
         function ev() {
             console.log("Inside ... " + templateName);
+            var myArgs = arguments;
             Ext.each(arguments, function(v, i) {
-                args["a" + i] = arguments[i];
+                args["a" + i] = myArgs[i];
             });
             args['control'] = control;
             args['widget'] = ww;
+            examine = {args:args, arg2: arguments};
             if((isValidFn != null) && (isValidFn(arguments) == false)) {return;}
             reason.server.execute(tpl.apply(args), true);
         };


diff -r 8e21fdf72d2aafb9e2540a9f8728ca344bde178c -r a335d40104009b890f57cfb0d3aa7d9cb4eaca7f yt/gui/reason/html/app/controller/widgets/ParameterFile.js
--- a/yt/gui/reason/html/app/controller/widgets/ParameterFile.js
+++ b/yt/gui/reason/html/app/controller/widgets/ParameterFile.js
@@ -33,26 +33,64 @@
     extend: 'Reason.controller.widgets.BaseWidget',
     requires: ['Reason.view.widgets.ParameterFileDisplay',
                'Reason.view.widgets.LevelStats',
+               'Reason.view.widgets.FieldPanel',
                'Reason.store.widgets.LevelInformation'],
     templates: {
         title: "Dataset: {widget.varname}",
         createDisplay: 'widget_store.create_pf_display({varname})',
-        getLevelInfo: 'widget_store["{widget.varname}"].deliver_level_stats()',
-        getFieldInfo: 'widget_store["{widget.varname}"].deliver_fields()',
+        retrieveField: 'widget_store["{widget.varname}"].deliver_field("{a1}")',
+        fieldSource: '<pre>{field_source}</pre>',
+        pfParams: '<table class="pftable">' +
+                  '<tr><th>Parameter</th><th>Value</th></tr>' +
+                  '<tr><td>Output Hash</td>' + 
+                  '<td>{output_hash}</td></tr>' +
+                  '<tr><td>Dimensionality</td>' +
+                  '<td>{dimensionality}</td></tr>' +
+                  '<tr><td>Refine by</td>' +
+                  '<td>{refine_by}</td></tr>' +
+                  '<tr><td>Domain Dimensions</td>' +
+                  '<td>{domain_dimensions}</td></tr>' +
+                  '<tr><td>Cosmological Simulation</td>' +
+                  '<td>{cosmological_simulation}</td></tr>' +
+                  '<tr><td>Current Redshift</td>' +
+                  '<td>{current_redshift}</td></tr>' +
+                  '<tr><td>Omega Matter</td>' +
+                  '<td>{omega_matter}</td></tr>' +
+                  '<tr><td>Omega Lambda</td>' +
+                  '<td>{omega_lambda}</td></tr>' +
+                  '<tr><td>Hubble Constant</td>' +
+                  '<td>{hubble_constant}</td></tr>' +
+                  '<tr><td>Current (sim) Time</td>' +
+                  '<td>{current_time}</td></tr>' +
+                  '<tr><td>Domain Left Edge</td>' +
+                  '<td>{domain_left_edge}</td></tr>' +
+                  '<tr><td>Domain Right Edge</td>' +
+                  '<td>{domain_right_edge}</td></tr>' +
+                  '</table>',
     },
 
     widgetTriggers: [
     ],
 
     executionTriggers: [
+        ['#fieldSelector', 'change', 'retrieveField'],
     ],
 
     viewRefs: [
         { ref:'levelStats', selector: '#levelStats'},
         { ref:'statsPanel', selector: '#statsPanel'},
+        { ref:'parametersPanel', selector: '#pfParams'},
+        { ref:'fieldPanel', selector: '#fieldPanel'},
+        { ref:'fieldSourcePanel', selector: '#fieldSourcePanel'},
+        { ref:'widgetPanel', selector: '#widgetpanel'},
     ],
 
     applyPayload: function(payload) {
+        if (payload['ptype'] == 'field_info') {
+            var source = this.templateManager.applyObject(
+                payload, 'fieldSource')
+            this.getFieldSourcePanel().update(source);
+        }
     },
 
     createView: function() {
@@ -63,12 +101,24 @@
         this.levelStatsDisplay = Ext.widget("levelstats", {
             store: this.levelDataStore,
         });
-        examine = this.levelStatsDisplay;
         this.dataView = Ext.widget("pfdisplay", {
              title: 'Data for ' + this.payload['varname'],
+             varname: this.payload['varname'],
         });
+        this.fieldDisplay = Ext.widget("fieldpanel");
+        fieldSelector = this.fieldDisplay.query("#fieldSelector")[0]
+        this.fieldStore = Ext.create("Reason.store.Fields")
+        this.fieldStore.loadData(wd['fields']);
+        fieldSelector.bindStore(this.fieldStore);
+
+        this.dataView.query("#fieldPanel")[0].add(this.fieldDisplay);
         this.dataView.query("#statsPanel")[0].add(this.levelStatsDisplay);
         this.createMyRefs(this.dataView.id);
+
+        var pfString = this.templateManager.applyObject(
+                wd['pf_info'], 'pfParams');
+        this.getParametersPanel().update(pfString);
+        this.applyExecuteHandlers(this.dataView);
         return this.dataView;
     },
 


diff -r 8e21fdf72d2aafb9e2540a9f8728ca344bde178c -r a335d40104009b890f57cfb0d3aa7d9cb4eaca7f yt/gui/reason/html/app/store/Fields.js
--- /dev/null
+++ b/yt/gui/reason/html/app/store/Fields.js
@@ -0,0 +1,39 @@
+/**********************************************************************
+Field store for Reason
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define('Reason.store.Fields', {
+    extend: 'Ext.data.Store',
+    fields: [
+        {name: 'text', type: 'string'}
+    ],
+    data: [],
+});
+


diff -r 8e21fdf72d2aafb9e2540a9f8728ca344bde178c -r a335d40104009b890f57cfb0d3aa7d9cb4eaca7f yt/gui/reason/html/app/view/widgets/FieldPanel.js
--- /dev/null
+++ b/yt/gui/reason/html/app/view/widgets/FieldPanel.js
@@ -0,0 +1,74 @@
+/**********************************************************************
+Field Info Display
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define("Reason.view.widgets.FieldPanel", {
+    extend: 'Ext.panel.Panel',
+    alias: 'widget.fieldpanel',
+    iconCls: 'graph',
+    autoScroll: true,
+    layout: {
+        type: 'vbox',
+        pack: 'start',
+        align: 'stretch',
+    },
+    width: '100%',
+    height: '100%',
+
+    items: [ 
+        {
+          xtype: 'combo',
+          text: 'Field',
+          itemId: 'fieldSelector',
+          height: 30,
+          width: 700,
+          queryMode: 'local',
+          editable: false,
+          triggerAction: 'all',
+          validateOnBlur: false,
+        }, {
+          xtype: 'panel',
+          title: 'Field Source',
+          itemId: 'fieldSourcePanel',
+          flex: 3.0,
+          width: 700,
+          autoScroll: true,
+          bodyCls: 'pfdisplay',
+        }, {
+          xtype: 'panel',
+          title: 'Field Parameters',
+          height: 200,
+          width: 700,
+          autoScroll: true,
+          bodyCls: 'pfdisplay',
+        }
+    ],
+});
+


diff -r 8e21fdf72d2aafb9e2540a9f8728ca344bde178c -r a335d40104009b890f57cfb0d3aa7d9cb4eaca7f yt/gui/reason/html/app/view/widgets/LevelStats.js
--- a/yt/gui/reason/html/app/view/widgets/LevelStats.js
+++ b/yt/gui/reason/html/app/view/widgets/LevelStats.js
@@ -44,10 +44,9 @@
         type: 'Numeric',
         position: 'bottom',
         fields: ['grid_rel', 'cell_rel'],
-        minimum: 0.0,
+        minimum: 0,
         grid: true,
         title: 'Relative Portion of Mesh',
-        roundToDecimal: function(v) { console.log(v); return(v); },
     }, {
         type: 'Category',
         position: 'left',


diff -r 8e21fdf72d2aafb9e2540a9f8728ca344bde178c -r a335d40104009b890f57cfb0d3aa7d9cb4eaca7f yt/gui/reason/html/app/view/widgets/ParameterFileDisplay.js
--- a/yt/gui/reason/html/app/view/widgets/ParameterFileDisplay.js
+++ b/yt/gui/reason/html/app/view/widgets/ParameterFileDisplay.js
@@ -42,7 +42,46 @@
     activeTab: 0,
 
     items: [
-        { xtype: 'panel',
+        { 
+          xtype: 'panel',
+          width: 600,
+          height: 500,
+          title: 'Dataset Information',
+          layout: {
+            type: 'absolute',
+          },
+          items: [
+            {
+              xtype: 'panel',
+              itemId: 'pfParams',
+              bodyCls: 'pfdisplay',
+              width: 600,
+              height: 300,
+              x: 0,
+              y: 0,
+              items: [],
+            }, {
+              xtype: 'panel',
+              itemId: 'widgetpanel',
+              width: 600,
+              height: 300,
+              x: 0,
+              y: 300,
+              items: [],
+            }
+          ],
+        }, {
+          xtype: 'panel',
+          itemId: 'fieldPanel',
+          title: 'Field Info',
+          layout: {
+            type: 'hbox',
+            pack: 'start',
+            align: 'stretch',
+          },
+          items: []
+        }, {
+          xtype: 'panel',
           itemId: 'statsPanel',
           title: 'Mesh Statistics',
           layout: {


diff -r 8e21fdf72d2aafb9e2540a9f8728ca344bde178c -r a335d40104009b890f57cfb0d3aa7d9cb4eaca7f yt/gui/reason/html/resources/css/style.css
--- a/yt/gui/reason/html/resources/css/style.css
+++ b/yt/gui/reason/html/resources/css/style.css
@@ -56,3 +56,13 @@
 .cell_waiting {
     background-color: #FF0000;
 }
+
+.pfdisplay {
+    font-family: monospace;
+    font-size: 120%;
+}
+
+table.pftable td, table.pftable th {
+    padding-left: 10px;
+    padding-right: 10px;
+}


diff -r 8e21fdf72d2aafb9e2540a9f8728ca344bde178c -r a335d40104009b890f57cfb0d3aa7d9cb4eaca7f yt/gui/reason/widget_store.py
--- a/yt/gui/reason/widget_store.py
+++ b/yt/gui/reason/widget_store.py
@@ -51,7 +51,6 @@
         print "DELIVERING", payload
         self.payload_handler.add_payload(payload)
 
-    @lockit
     def create_slice(self, pf, center, axis, field, onmax):
         if onmax: 
             center = pf.h.find_max('Density')[1]
@@ -75,7 +74,6 @@
                          'initial_transform' : trans}
         self._add_widget(pw, widget_data)
 
-    @lockit
     def create_proj(self, pf, axis, field, weight):
         if weight == "None": weight = None
         axis = inv_axis_names[axis.lower()]
@@ -94,7 +92,6 @@
                        'colorbar': cb}
         self._add_widget(pw, widget_data)
 
-    @lockit
     def create_grid_dataview(self, pf):
         levels = pf.h.grid_levels
         left_edge = pf.h.grid_left_edge
@@ -120,11 +117,11 @@
                    }
         self.payload_handler.add_payload(payload)
 
-    @lockit
     def create_pf_display(self, pf):
         widget = ParameterFileWidget(pf)
         widget_data = {'fields': widget._field_list(),
                        'level_stats': widget._level_stats(),
+                       'pf_info': widget._pf_info(),
                       }
         self._add_widget(widget, widget_data)
 
@@ -139,7 +136,7 @@
         field_list = list(set(self.pf.h.field_list
                             + self.pf.h.derived_field_list))
         field_list.sort()
-        return field_list
+        return [dict(text = field) for field in field_list]
 
     def _level_stats(self):
         level_data = []
@@ -155,3 +152,19 @@
                                'cell_rel': int(100*cell_count/ncells),
                                'grid_rel': int(100*grid_count/ngrids)})
         return level_data
+
+    def _pf_info(self):
+        tr = {}
+        for k, v in self.pf._mrep._attrs.items():
+            if isinstance(v, na.ndarray):
+                tr[k] = v.tolist()
+            else:
+                tr[k] = v
+        return tr
+
+    def deliver_field(self, field):
+        ph = PayloadHandler()
+        ph.widget_payload(self,
+            {'ptype':'field_info',
+             'field_source': self.pf.field_info[field].get_source() })
+        return



https://bitbucket.org/yt_analysis/yt/changeset/5bf872a2de60/
changeset:   5bf872a2de60
branch:      yt
user:        MatthewTurk
date:        2012-06-13 16:13:45
summary:     Fixing zoom slider, variable assignment name for the heartbeat, and the field
selection in plot window.
affected #:  4 files

diff -r a335d40104009b890f57cfb0d3aa7d9cb4eaca7f -r 5bf872a2de6024fc108608f41839c5bbec20a310 yt/gui/reason/bottle_mods.py
--- a/yt/gui/reason/bottle_mods.py
+++ b/yt/gui/reason/bottle_mods.py
@@ -58,7 +58,6 @@
     count = 0
     debug = False
 
-
     def __new__(cls, *p, **k):
         self = object.__new__(cls, *p, **k)
         self.__dict__ = cls._shared_state


diff -r a335d40104009b890f57cfb0d3aa7d9cb4eaca7f -r 5bf872a2de6024fc108608f41839c5bbec20a310 yt/gui/reason/html/app/controller/ServerCommunication.js
--- a/yt/gui/reason/html/app/controller/ServerCommunication.js
+++ b/yt/gui/reason/html/app/controller/ServerCommunication.js
@@ -48,7 +48,7 @@
         this.heartbeat = this.taskRunner.start(
             {run: this.heartbeatCall,
              interval: 250});
-        this.heartbeat = this.taskRunner.start(
+        this.dataObjectBeat = this.taskRunner.start(
             {run: this.dataObjectsCall,
              interval: 5000});
         this.callParent(arguments);
@@ -80,6 +80,7 @@
     heartbeatCall: function() {
         if (heartbeatRequest == true) return;
         heartbeatRequest = true;
+        console.log("Sending heartbeat");
         yt_rpc.ExtDirectREPL.heartbeat(
             {}, function(f, a) {
                 heartbeatRequest = false;


diff -r a335d40104009b890f57cfb0d3aa7d9cb4eaca7f -r 5bf872a2de6024fc108608f41839c5bbec20a310 yt/gui/reason/html/app/controller/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
@@ -42,7 +42,7 @@
         createProj: 'widget_store.create_proj({pfname}, "{axis}",' + 
                      '"{field}", "{weight}")',
         scrollZoom: 'widget_store["{widget.varname}"].scroll_zoom({a1})',
-        fieldChange: 'widget_store["{widget.varname}"].set_current_field("{a1.data[\'field1\']}")',
+        fieldChange: 'widget_store["{widget.varname}"].set_current_field("{a1}")',
         singleUpArrow:    'widget_store["{widget.varname}"].pan_rel(( 0.0, -0.1))',
         singleRightArrow: 'widget_store["{widget.varname}"].pan_rel(( 0.1,  0.0))',
         singleDownArrow:  'widget_store["{widget.varname}"].pan_rel(( 0.0   0.1))',
@@ -80,7 +80,7 @@
 
     executionTriggers: [
         ['#zoomSlider', 'changecomplete', 'scrollZoom'],
-        ['#fieldSelector', 'select', 'fieldChange'],
+        ['#fieldSelector', 'change', 'fieldChange'],
         ['#singleuparrow', 'click', 'singleUpArrow'],
         ['#singlerightarrow', 'click', 'singleRightArrow'],
         ['#singledownarrow', 'click', 'singleDownArrow'],


diff -r a335d40104009b890f57cfb0d3aa7d9cb4eaca7f -r 5bf872a2de6024fc108608f41839c5bbec20a310 yt/gui/reason/html/app/view/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/view/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/view/widgets/PlotWindow.js
@@ -72,7 +72,7 @@
             itemId: 'zoomSlider',
             minValue: 0,
             maxValue: 100,
-            increment: 0.1,
+            increment: 1,
             x: 100, y: 410,
             width: 400,
         },{



https://bitbucket.org/yt_analysis/yt/changeset/4d83e602b346/
changeset:   4d83e602b346
branch:      yt
user:        MatthewTurk
date:        2012-06-13 16:33:11
summary:     Fixing progress bar update criteria.
affected #:  1 file

diff -r 5bf872a2de6024fc108608f41839c5bbec20a310 -r 4d83e602b346669ce531f8da88485b13a8cc526a yt/gui/reason/extdirect_repl.py
--- a/yt/gui/reason/extdirect_repl.py
+++ b/yt/gui/reason/extdirect_repl.py
@@ -712,8 +712,8 @@
 
     def update(self, val):
         # An update is only meaningful if it's on the order of 1/100 or greater
-        if ceil(100*self.last / self.maxval) + 1 == \
-           floor(100*val / self.maxval) or val == self.maxval:
+
+        if (val - self.last) > (self.maxval / 100.0):
             self.last = val
             self.payload_handler.add_payload(
                 {'type': 'widget_payload',



https://bitbucket.org/yt_analysis/yt/changeset/8ae9c46e4aff/
changeset:   8ae9c46e4aff
branch:      yt
user:        MatthewTurk
date:        2012-06-13 16:44:58
summary:     Removing completely the streamline, grid view and isocontour views.  They will
be replaced will a complete 3D scene instead.
affected #:  1 file

diff -r 4d83e602b346669ce531f8da88485b13a8cc526a -r 8ae9c46e4aff7aa8a856c93aa8fc2fa1cd379bcc yt/gui/reason/extdirect_repl.py
--- a/yt/gui/reason/extdirect_repl.py
+++ b/yt/gui/reason/extdirect_repl.py
@@ -460,182 +460,6 @@
                                          'name': '_tpm',
                                          'widget_data_name': '_twidget_data'})
 
-    @lockit
-    def create_slice(self, pfname, center, axis, field, onmax):
-        if not onmax: 
-            center_string = \
-              "na.array([%(c1)0.20f,%(c2)0.20f, %(c3)0.20f],dtype='float64')" \
-                % dict(c1 = float(center[0]),
-                       c2 = float(center[1]),
-                       c3 = float(center[2]))
-        else:
-            center_string = "_tpf.h.find_max('Density')[1]"
-        funccall = """
-        _tpf = %(pfname)s
-        _taxis = %(axis)s
-        _tfield = "%(field)s"
-        _tcenter = %(center_string)s
-        _tcoord = _tcenter[_taxis]
-        _tsl = _tpf.h.slice(_taxis, _tcoord, center = _tcenter, periodic = True)
-        _txax, _tyax = x_dict[_taxis], y_dict[_taxis]
-        DLE, DRE = _tpf.domain_left_edge, _tpf.domain_right_edge
-        from yt.visualization.plot_window import PWViewerExtJS
-        _tpw = PWViewerExtJS(_tsl, (DLE[_txax], DRE[_txax], DLE[_tyax], DRE[_tyax]), setup = False)
-        _tpw.set_current_field("%(field)s")
-        _tfield_list = list(set(_tpf.h.field_list + _tpf.h.derived_field_list))
-        _tfield_list.sort()
-        _tcb = _tpw._get_cbar_image()
-        _ttrans = _tpw._field_transform[_tpw._current_field].name
-        _twidget_data = {'fields': _tfield_list,
-                         'initial_field': _tfield,
-                         'title': "%%s Slice" %% (_tpf),
-                         'colorbar': _tcb,
-                         'initial_transform' : _ttrans}
-        """ % dict(pfname = pfname,
-                   center_string = center_string,
-                   axis = inv_axis_names[axis],
-                   field=field)
-        # There is a call to do this, but I have forgotten it ...
-        funccall = "\n".join((line.strip() for line in funccall.splitlines()))
-        self.execute(funccall, hide = True)
-        self.execution_thread.queue.put({'type': 'add_widget',
-                                         'name': '_tpw',
-                                         'widget_data_name': '_twidget_data'})
-
-    @lockit
-    def create_isocontours(self, pfname, field, value, sampling_field):
-        funccall = """
-        _tpf = %(pfname)s
-        _tfield = "%(field)s"
-        _tvalue = %(value)s
-        _tsample_values = "%(sampling_field)s"
-        _tdd = _tpf.h.all_data()
-        _tiso = _tdd.extract_isocontours(_tfield, _tvalue, rescale = True,
-                                         sample_values = _tsample_values)
-        from yt.funcs import YTEmptyClass
-        _tpw = YTEmptyClass()
-        _tpw._widget_name = 'isocontour_viewer'
-        _tpw._ext_widget_id = None
-        _tverts = _tiso[0].ravel().tolist()
-        _tc = (apply_colormap(na.log10(_tiso[1]))).squeeze()
-        _tcolors = na.empty((_tc.shape[0] * 3, 4), dtype='float32')
-        _tcolors[0::3,:] = _tc
-        _tcolors[1::3,:] = _tc
-        _tcolors[2::3,:] = _tc
-        _tcolors = (_tcolors.ravel()/255.0).tolist()
-        _twidget_data = {'vertex_positions': _tverts, 'vertex_colors': _tcolors}
-        """ % dict(pfname=pfname, value=value, sampling_field=sampling_field, field=field)
-        # There is a call to do this, but I have forgotten it ...
-        funccall = "\n".join((line.strip() for line in funccall.splitlines()))
-        self.execute(funccall, hide = True)
-        self.execution_thread.queue.put({'type': 'add_widget',
-                                         'name' : '_tpw',
-                                         'widget_data_name': '_twidget_data'})
-
-
-    @lockit
-    def create_grid_viewer(self, pfname):
-        funccall = """
-        _tpf = %(pfname)s
-        """ % dict(pfname = pfname)
-        funccall = "\n".join((line.strip() for line in funccall.splitlines()))
-        self.execute(funccall, hide = True)
-        self.execution_thread.queue.join()
-        pf = self.locals['_tpf']
-        corners = pf.h.grid_corners
-        levels = pf.h.grid_levels
-        colors = apply_colormap(levels*1.0,
-                                color_bounds=[0,pf.h.max_level],
-                                cmap_name="algae").repeat(24,axis=0)[:,0,:]*1.0/255.
-        colors[:,3]=0.7
-        colors = colors.ravel().tolist()
-        
-        vertices = []
-        
-        trans  = [0, 1, 2, 7, 5, 6, 3, 4]
-        order  = [0, 1, 1, 2, 2, 3, 3, 0]
-        order += [4, 5, 5, 6, 6, 7, 7, 4]
-        order += [0, 4, 1, 5, 2, 6, 3, 7]
-
-        for g in xrange(corners.shape[2]):
-            for c in order:
-                ci = trans[c]
-                vertices.append(corners[ci,:,g])
-        vertices = na.concatenate(vertices).tolist()
-        uu = str(uuid.uuid1()).replace("-","_")
-        varname = "gv_%s" % (uu)
-        payload = {'type': 'widget',
-                   'widget_type': 'grid_viewer',
-                   'varname': varname, # Is just "None"
-                   'data': dict(n_vertices = len(vertices)/3,
-                                vertex_positions = vertices,
-                                vertex_colors = colors)
-                   }
-        self.execute("%s = None\n" % (varname), hide=True)
-        self.payload_handler.add_payload(payload)
-
-    @lockit
-    def create_streamline_viewer(self, pfname):
-        funccall = """
-        _tpf = %(pfname)s
-        """ % dict(pfname = pfname)
-        funccall = "\n".join((line.strip() for line in funccall.splitlines()))
-        self.execute(funccall, hide = True)
-        pf = self.locals['_tpf']
-
-        c = na.array([0.5]*3)
-        N = 100
-        scale = 1.0
-        pos_dx = na.random.random((N,3))*scale-scale/2.
-        pos = c+pos_dx
-        
-        SL = Streamlines(pf,pos,'x-velocity', 'y-velocity', 'z-velocity', length=1.0, get_magnitude=True)
-        SL.integrate_through_volume()
-        streamlist=[]
-        stream_lengths = []
-        for i,stream in enumerate(SL.streamlines):
-            stream_lengths.append( stream[na.all(stream != 0.0, axis=1)].shape[0])
-        streamlist = SL.streamlines.flatten()
-        streamlist = streamlist[streamlist!=0.0].tolist()
-
-        stream_colors = SL.magnitudes.flatten()
-        stream_colors = na.log10(stream_colors[stream_colors > 0.0])
-        stream_colors = apply_colormap(stream_colors, cmap_name='algae')
-        stream_colors = stream_colors*1./255.
-        stream_colors[:,:,3] = 0.8
-        stream_colors = stream_colors.flatten().tolist()
-
-        uu = str(uuid.uuid1()).replace("-","_")
-        varname = "sl_%s" % (uu)
-        payload = {'type': 'widget',
-                   'widget_type': 'streamline_viewer',
-                   'varname': varname, # Is just "None"
-                   'data': dict(n_streamlines = SL.streamlines.shape[0],
-                                stream_positions = streamlist,
-                                stream_colors = stream_colors,
-                                stream_lengths = stream_lengths)
-                   }
-        self.execute("%s = None\n" % (varname), hide=True)
-        self.payload_handler.add_payload(payload)
-
-    @lockit
-    def object_creator(self, pfname, objtype, objargs):
-        funccall = "_tobjargs = {}\n"
-        for argname, argval in objargs.items():
-            # These arguments may need further sanitization
-            if isinstance(argval, types.StringTypes):
-                argval = "'%s'" % argval
-            funccall += "_tobjargs['%(argname)s'] = %(argval)s\n" % dict(
-                    argname = argname, argval = argval)
-        funccall += """
-        _tpf = %(pfname)s
-        _tobjclass = getattr(_tpf.h, '%(objtype)s')
-        data_objects.append(_tobjclass(**_tobjargs))
-        """ % dict(pfname = pfname, objtype = objtype)
-        funccall = "\n".join((line.strip() for line in funccall.splitlines()))
-        self.execute(funccall, hide = False)
-        pf = self.locals['_tpf']
-
 class ExtDirectParameterFileList(BottleDirectRouter):
     my_name = "ExtDirectParameterFileList"
     api_url = "pflist"



https://bitbucket.org/yt_analysis/yt/changeset/80c1066b65d0/
changeset:   80c1066b65d0
branch:      yt
user:        MatthewTurk
date:        2012-06-13 22:56:27
summary:     Fixed a routing bug that prevent dynamic routing of new stuff; will have to
(eventually) clean up some paths.  Added most of pannable map, although it's
running into some trickiness with the DIV locations, and I can't yet figure out
how to get the afterrender bit to work.
affected #:  9 files

diff -r 8ae9c46e4aff7aa8a856c93aa8fc2fa1cd379bcc -r 80c1066b65d06f2ae89d757df1d8018b6a70a298 yt/gui/reason/extdirect_repl.py
--- a/yt/gui/reason/extdirect_repl.py
+++ b/yt/gui/reason/extdirect_repl.py
@@ -195,7 +195,7 @@
                               _session_py = ("/session.py", "GET"),
                               _highlighter_css = ("/highlighter.css", "GET"),
                               _extjs = ("/resources/extjs-4.1.0/:path#.+#", "GET"),
-                              _app = ("/:path#.+#", "GET"),
+                              _app = ("/reason/:path#.+#", "GET"),
                               )
         for v, args in preroute_table.items():
             preroute(args[0], method=args[1])(getattr(self, v))
@@ -512,13 +512,13 @@
              'log_entry':msg})
 
 if os.path.exists(os.path.expanduser("~/.yt/favicon.ico")):
-    ico = os.path.expanduser("~/.yt/favicon.ico")
+    ico = os.path.expanduser("~/.yt/")
 else:
-    ico = os.path.join(local_dir, "html", "images", "favicon.ico")
+    ico = os.path.join(local_dir, "html", "resources", "images")
 @route("/favicon.ico", method="GET")
 def _favicon_ico():
-    response.headers['Content-Type'] = "image/x-icon"
-    return open(ico).read()
+    print ico
+    return static_file("favicon.ico", ico)
 
 class ExtProgressBar(object):
     def __init__(self, title, maxval):


diff -r 8ae9c46e4aff7aa8a856c93aa8fc2fa1cd379bcc -r 80c1066b65d06f2ae89d757df1d8018b6a70a298 yt/gui/reason/html/app.js
--- a/yt/gui/reason/html/app.js
+++ b/yt/gui/reason/html/app.js
@@ -41,7 +41,7 @@
                ],
     name: 'Reason',
 
-    appFolder: 'app',
+    appFolder: 'reason/app',
 
     launch: function() {
         reason = this;


diff -r 8ae9c46e4aff7aa8a856c93aa8fc2fa1cd379bcc -r 80c1066b65d06f2ae89d757df1d8018b6a70a298 yt/gui/reason/html/app/controller/WidgetDirector.js
--- a/yt/gui/reason/html/app/controller/WidgetDirector.js
+++ b/yt/gui/reason/html/app/controller/WidgetDirector.js
@@ -30,6 +30,7 @@
                "Reason.controller.widgets.ProgressBar",
                "Reason.controller.widgets.GridDataViewer",
                "Reason.controller.widgets.ParameterFile",
+               "Reason.controller.widgets.PannableMap",
     ],
     stores: ['WidgetTypes', 'WidgetInstances'],
     views: ['WidgetTypesGrid', 'WidgetInstancesGrid'],


diff -r 8ae9c46e4aff7aa8a856c93aa8fc2fa1cd379bcc -r 80c1066b65d06f2ae89d757df1d8018b6a70a298 yt/gui/reason/html/app/controller/widgets/PannableMap.js
--- a/yt/gui/reason/html/app/controller/widgets/PannableMap.js
+++ b/yt/gui/reason/html/app/controller/widgets/PannableMap.js
@@ -23,54 +23,55 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ***********************************************************************/
 
-var WidgetPannableMap = function(python_varname, widget_data) {
-    this.id = python_varname;
-    this.widget_data = widget_data;
+Ext.define("Reason.controller.widgets.PannableMap", {
+    extend: 'Reason.controller.widgets.BaseWidget',
+    requires: ['Reason.view.widgets.PannableMapView'],
 
-    viewport.get("center-panel").add(
-        {
-            xtype: 'panel',
-            id: "pm_" + this.id,
-            title: "Pannable Map",
-            iconCls: 'graph',
-            autoScroll: true,
-            layout:'absolute',
-            closable: true,
-            items: [ 
-                {
-                    xtype:'box',
-                    autoEl: {
-                        tag: 'div',
-                        id: "map_" + this.id,
-                        width: 512,
-                        height: 512,
-                    },
-                    x: 10,
-                    y: 10,
-                    width: 512,
-                    height: 512,
-                    listeners: {afterrender:
-                        function() {
-                          var map = new L.Map('map_' + python_varname, {
-                                  center: new L.LatLng(0.0, 0.0),
-                                  zoom: 0,
-                                  });
-                          var cloudmadeUrl = widget_data['prefix'] + '/map/{z}/{x}/{y}.png';
-                          cloudmade = new L.TileLayer(cloudmadeUrl, {maxZoom: 18});
-                          map.addLayer(cloudmade);
-                    }},
-                }  
-            ]
-        }
-    );
+    templates: {
+        title: "Map View for {widget.varname}",
+    },
 
-    viewport.get("center-panel").activate("pm_" + this.id);
-    viewport.doLayout();
-    this.panel = viewport.get("center-panel").get("pm_" + this.id);
-    this.panel.doLayout();
-    examine = this.panel;
+    widgetTriggers: [
 
-    this.accept_results = function(payload) { }
-}
+    ],
 
-widget_types['pannable_map'] = WidgetPannableMap;
+    executionTriggers: [
+        ['#mapbox', 'afterrender', 'setupLeaflet'],
+    ],
+
+    viewRefs: [
+        { ref: 'mapBox', selector: '#mapbox' },
+    ],
+
+    applyPayload: function(payload) {
+        return;
+    },
+
+    setupLeaflet: function() {
+        this.leafletMap = new L.Map(this.getMapBox().getEl().dom,
+            {
+                center: new L.LatLng(0.0, 0.0),
+                zoom: 0,
+            });
+        var ytMapURL = this.payload.data['prefix'] + '/map/{z}/{x}/{y}.png';
+        this.tileLayer = new L.TileLayer(ytMapURL, {maxZoom: 18});
+        this.leafletMap.addLayer(this.tileLayer)
+    },
+
+    createView: function() {
+        this.dataView = Ext.widget("mapview", {
+             title: 'Pannable Map of ' + this.payload['field'],
+        });
+        this.createMyRefs(this.dataView.id);
+        this.applyExecuteHandlers(this.dataView);
+        return this.dataView;
+    },
+
+    statics: {
+        widgetName: "pannable_map",
+        displayName: "Pannable Map",
+        supportsDataObjects: false,
+        supportsParameterFiles: false,
+        preCreation: function(obj) { },
+    },
+});


diff -r 8ae9c46e4aff7aa8a856c93aa8fc2fa1cd379bcc -r 80c1066b65d06f2ae89d757df1d8018b6a70a298 yt/gui/reason/html/app/controller/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
@@ -70,11 +70,11 @@
         recenterImage:   'widget_store["{widget.varname}"].image_recenter(' +
                          '{x}, {y}, {w}, {h})',
         dragImage:       'widget_store["{widget.varname}"].pan_rel(({rel_x}, {rel_y}))',
+        createPannableMap: 'widget_store.create_mapview("{widget.varname}")',
     },
 
     widgetTriggers: [
         ['#uploadimage', 'click', 'uploadImage'],
-        ['#pannablemap', 'click', 'createPannableMap'],
         ['#imagepanel', 'afterrender', 'setupClickImage'],
     ],
 
@@ -97,6 +97,7 @@
         ['#colormap', 'select', 'adjustColormap'],
         ['#contourapply', 'click', 'adjustContours'],
         ['#vectorsapply', 'click', 'adjustVectors'],
+        ['#pannablemap', 'click', 'createPannableMap'],
     ],
 
     viewRefs: [
@@ -252,10 +253,6 @@
             });
     },
 
-    createPannableMap: function() {
-        alert("Not implemented!");
-    },
-
     setupClickImage: function(c) {
         var controller = this;
         var dragStartPos = {x:-1, y:-1};


diff -r 8ae9c46e4aff7aa8a856c93aa8fc2fa1cd379bcc -r 80c1066b65d06f2ae89d757df1d8018b6a70a298 yt/gui/reason/html/app/view/widgets/PannableMapView.js
--- /dev/null
+++ b/yt/gui/reason/html/app/view/widgets/PannableMapView.js
@@ -0,0 +1,47 @@
+/**********************************************************************
+The Pannable Map Widget
+
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define("Reason.view.widgets.PannableMapView", {
+    extend: 'Ext.panel.Panel',
+    title: 'This should not be visible.',
+    alias: 'widget.mapview',
+    iconCls: 'graph',
+    autoScroll: true,
+    layout: 'absolute',
+    width: '100%',
+    height: '100%',
+    closable: true,
+    
+    items: [ 
+        {
+          xtype:'panel',
+          x: 10,
+          y: 10,
+          width: 512,
+          height: 512,
+          id: 'mapbox',
+        }  
+    ],
+});


diff -r 8ae9c46e4aff7aa8a856c93aa8fc2fa1cd379bcc -r 80c1066b65d06f2ae89d757df1d8018b6a70a298 yt/gui/reason/html/index.html
--- a/yt/gui/reason/html/index.html
+++ b/yt/gui/reason/html/index.html
@@ -9,17 +9,17 @@
 
     <!-- LIBS --><link rel="stylesheet" type="text/css" href="resources/extjs-4.1.0/resources/css/ext-all-gray.css">
-    <link rel="stylesheet" type="text/css" href="resources/css/style.css">
+    <link rel="stylesheet" type="text/css" href="reason/resources/css/style.css"><link rel="stylesheet" type="text/css" href="highlighter.css"><script type="text/javascript" src="resources/extjs-4.1.0/ext-all-debug.js"></script>
-    <script type="text/javascript" src="app.js"></script>
+    <script type="text/javascript" src="reason/app.js"></script><script type="text/javascript" src="ext-repl-api.js"></script><script type="text/javascript" src="resources/ext-pflist-api.js"></script><!-- LEAFLET STUFF -->
-    <script type="text/javascript" src="resources/leaflet/leaflet.js"></script>
-    <link rel="stylesheet" href="resources/leaflet/leaflet.css" />
+    <script type="text/javascript" src="reason/resources/leaflet/leaflet.js"></script>
+    <link rel="stylesheet" href="reason/resources/leaflet/leaflet.css" /></head><body>


diff -r 8ae9c46e4aff7aa8a856c93aa8fc2fa1cd379bcc -r 80c1066b65d06f2ae89d757df1d8018b6a70a298 yt/gui/reason/pannable_map.py
--- a/yt/gui/reason/pannable_map.py
+++ b/yt/gui/reason/pannable_map.py
@@ -61,8 +61,8 @@
         # slices:
         self.data[self.field] = self.data[self.field].astype("float64")
 
-    #@exc_writeout
     def map(self, L, x, y):
+        mylog.debug("Hello!")
         dd = 1.0 / (2.0**(int(L)))
         relx = int(x) * dd
         rely = int(y) * dd


diff -r 8ae9c46e4aff7aa8a856c93aa8fc2fa1cd379bcc -r 80c1066b65d06f2ae89d757df1d8018b6a70a298 yt/gui/reason/widget_store.py
--- a/yt/gui/reason/widget_store.py
+++ b/yt/gui/reason/widget_store.py
@@ -125,6 +125,18 @@
                       }
         self._add_widget(widget, widget_data)
 
+    def create_mapview(self, widget_name):
+        widget = self[widget_name]
+        # We want multiple maps simultaneously
+        uu = "/%s/%s" % (getattr(self.repl, "_global_token", ""),
+                        str(uuid.uuid1()).replace("-","_"))
+        from .pannable_map import PannableMapServer
+        data = widget.data_source
+        field_name = widget._current_field
+        pm = PannableMapServer(data, field_name, route_prefix = uu)
+        widget_data = {'prefix': uu, 'field':field_name}
+        self._add_widget(pm, widget_data)
+
 class ParameterFileWidget(object):
     _ext_widget_id = None
     _widget_name = "parameterfile"



https://bitbucket.org/yt_analysis/yt/changeset/768c73ca9aca/
changeset:   768c73ca9aca
branch:      yt
user:        MatthewTurk
date:        2012-06-14 02:24:27
summary:     Pannable map turns on now.
affected #:  1 file

diff -r 80c1066b65d06f2ae89d757df1d8018b6a70a298 -r 768c73ca9acae8178e31950dce7fe814dd819cca yt/gui/reason/html/app/controller/widgets/PannableMap.js
--- a/yt/gui/reason/html/app/controller/widgets/PannableMap.js
+++ b/yt/gui/reason/html/app/controller/widgets/PannableMap.js
@@ -32,11 +32,10 @@
     },
 
     widgetTriggers: [
-
+        ['#mapbox', 'afterrender', 'setupLeaflet'],
     ],
 
     executionTriggers: [
-        ['#mapbox', 'afterrender', 'setupLeaflet'],
     ],
 
     viewRefs: [



https://bitbucket.org/yt_analysis/yt/changeset/b948ebd37ad3/
changeset:   b948ebd37ad3
branch:      yt
user:        MatthewTurk
date:        2012-06-14 16:39:28
summary:     Changing the LeafLet rendering to occur after layout, rather than after the
render, fixes the issues with the placement of the tiles.  Pannable map is now
done.
affected #:  3 files

diff -r 768c73ca9acae8178e31950dce7fe814dd819cca -r b948ebd37ad39f24fd67ebb0d56bdbd7ee03eb7d yt/gui/reason/html/app/controller/widgets/PannableMap.js
--- a/yt/gui/reason/html/app/controller/widgets/PannableMap.js
+++ b/yt/gui/reason/html/app/controller/widgets/PannableMap.js
@@ -32,7 +32,7 @@
     },
 
     widgetTriggers: [
-        ['#mapbox', 'afterrender', 'setupLeaflet'],
+        ['#mapbox', 'afterlayout', 'setupLeaflet'],
     ],
 
     executionTriggers: [
@@ -47,14 +47,16 @@
     },
 
     setupLeaflet: function() {
-        this.leafletMap = new L.Map(this.getMapBox().getEl().dom,
+        var toRender = this.getMapBox().getEl().dom.childNodes[0].id;
+        this.leafletMap = new L.Map(toRender,
             {
-                center: new L.LatLng(0.0, 0.0),
-                zoom: 0,
+                center: new L.LatLng(0, 0),
+                zoom: 1,
             });
         var ytMapURL = this.payload.data['prefix'] + '/map/{z}/{x}/{y}.png';
         this.tileLayer = new L.TileLayer(ytMapURL, {maxZoom: 18});
         this.leafletMap.addLayer(this.tileLayer)
+        examine = toRender;
     },
 
     createView: function() {


diff -r 768c73ca9acae8178e31950dce7fe814dd819cca -r b948ebd37ad39f24fd67ebb0d56bdbd7ee03eb7d yt/gui/reason/html/app/view/widgets/PannableMapView.js
--- a/yt/gui/reason/html/app/view/widgets/PannableMapView.js
+++ b/yt/gui/reason/html/app/view/widgets/PannableMapView.js
@@ -37,11 +37,12 @@
     items: [ 
         {
           xtype:'panel',
-          x: 10,
-          y: 10,
+          layout: 'absolute',
+          x: 0,
+          y: 0,
           width: 512,
           height: 512,
-          id: 'mapbox',
+          itemId: 'mapbox',
         }  
     ],
 });


diff -r 768c73ca9acae8178e31950dce7fe814dd819cca -r b948ebd37ad39f24fd67ebb0d56bdbd7ee03eb7d yt/gui/reason/pannable_map.py
--- a/yt/gui/reason/pannable_map.py
+++ b/yt/gui/reason/pannable_map.py
@@ -62,7 +62,6 @@
         self.data[self.field] = self.data[self.field].astype("float64")
 
     def map(self, L, x, y):
-        mylog.debug("Hello!")
         dd = 1.0 / (2.0**(int(L)))
         relx = int(x) * dd
         rely = int(y) * dd



https://bitbucket.org/yt_analysis/yt/changeset/ab7eb0fb9605/
changeset:   ab7eb0fb9605
branch:      yt
user:        MatthewTurk
date:        2012-06-14 17:26:43
summary:     Adding a loading image to the plot window.
affected #:  3 files

diff -r b948ebd37ad39f24fd67ebb0d56bdbd7ee03eb7d -r ab7eb0fb960568de61c8f23b00738cbfac598cc9 yt/gui/reason/html/app/view/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/view/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/view/widgets/PlotWindow.js
@@ -52,7 +52,7 @@
         }, {
             xtype:'image',
             itemId: 'colorbar',
-            src: 'nothing.png',
+            src: 'reason/resources/images/loading.png',
             style: 'border: 1px solid #000000;',
             x: 510,
             y: 10,


diff -r b948ebd37ad39f24fd67ebb0d56bdbd7ee03eb7d -r ab7eb0fb960568de61c8f23b00738cbfac598cc9 yt/gui/reason/html/app/view/widgets/PlotWindowCreator.js
--- a/yt/gui/reason/html/app/view/widgets/PlotWindowCreator.js
+++ b/yt/gui/reason/html/app/view/widgets/PlotWindowCreator.js
@@ -118,7 +118,7 @@
               }],
               buttons: [
                   {
-                      text: 'Project', itemId: 'create',
+                      text: 'Go', itemId: 'create',
                   },{
                       text: 'Cancel', itemId: 'cancel',
                   }


diff -r b948ebd37ad39f24fd67ebb0d56bdbd7ee03eb7d -r ab7eb0fb960568de61c8f23b00738cbfac598cc9 yt/gui/reason/html/resources/images/loading.png
Binary file yt/gui/reason/html/resources/images/loading.png has changed



https://bitbucket.org/yt_analysis/yt/changeset/7221f7734654/
changeset:   7221f7734654
branch:      yt
user:        MatthewTurk
date:        2012-06-14 18:04:17
summary:     Scroll to bottom with the log entries
affected #:  2 files

diff -r ab7eb0fb960568de61c8f23b00738cbfac598cc9 -r 7221f7734654c48e18b1b45ff34a7b1d30610fdd yt/gui/reason/html/app/controller/Logging.js
--- a/yt/gui/reason/html/app/controller/Logging.js
+++ b/yt/gui/reason/html/app/controller/Logging.js
@@ -34,6 +34,12 @@
     stores: [ 'LogEntries' ],
     view: ['LoggingGrid'],
 
+    refs: [
+        { ref: 'logEntries',
+          selector: '#logentries'
+        },
+    ],
+
     init: function() {
         this.application.addListener({
             payloadlogentry: {fn: this.addLogPayload, scope: this},
@@ -47,5 +53,8 @@
 
     addLogEntry: function(text) {
         this.getLogEntriesStore().add({record: text});
+        var i = this.getLogEntriesStore().getCount();
+        examine = this.getLogEntries();
+        this.getLogEntries().getView().focusRow(i - 1);
     },
 });


diff -r ab7eb0fb960568de61c8f23b00738cbfac598cc9 -r 7221f7734654c48e18b1b45ff34a7b1d30610fdd yt/gui/reason/html/app/view/LoggingGrid.js
--- a/yt/gui/reason/html/app/view/LoggingGrid.js
+++ b/yt/gui/reason/html/app/view/LoggingGrid.js
@@ -34,5 +34,6 @@
     alias: 'widget.logginggrid',
     title: 'Logging Output',
     store: 'LogEntries',
+    itemId: 'logentries',
     columns: [ {header: 'Message', dataIndex:'record', flex:1} ],
 });



https://bitbucket.org/yt_analysis/yt/changeset/554a25a4081d/
changeset:   554a25a4081d
branch:      yt
user:        MatthewTurk
date:        2012-06-14 18:20:28
summary:     Monospacing the log entries.
affected #:  2 files

diff -r 7221f7734654c48e18b1b45ff34a7b1d30610fdd -r 554a25a4081db97e16840015e2988e351e58892e yt/gui/reason/html/app/view/LoggingGrid.js
--- a/yt/gui/reason/html/app/view/LoggingGrid.js
+++ b/yt/gui/reason/html/app/view/LoggingGrid.js
@@ -36,4 +36,7 @@
     store: 'LogEntries',
     itemId: 'logentries',
     columns: [ {header: 'Message', dataIndex:'record', flex:1} ],
+    viewConfig: {
+        cls: 'logentry',
+    },
 });


diff -r 7221f7734654c48e18b1b45ff34a7b1d30610fdd -r 554a25a4081db97e16840015e2988e351e58892e yt/gui/reason/html/resources/css/style.css
--- a/yt/gui/reason/html/resources/css/style.css
+++ b/yt/gui/reason/html/resources/css/style.css
@@ -47,6 +47,11 @@
     font-size: 120%;
 }
 
+.logentry .x-grid-cell {
+    font-family: monospace;
+    font-size: 120%;
+}
+
 tr.codeview td, tr.codeview pre {
     padding-left: 20px;
     font-family: monospace;



https://bitbucket.org/yt_analysis/yt/changeset/564843888d10/
changeset:   564843888d10
branch:      yt
user:        MatthewTurk
date:        2012-06-14 19:29:45
summary:     Select code in the notebook now.
affected #:  1 file

diff -r 554a25a4081db97e16840015e2988e351e58892e -r 564843888d106893768aa35835225ab2ac1c5dd8 yt/gui/reason/html/app/view/CellView.js
--- a/yt/gui/reason/html/app/view/CellView.js
+++ b/yt/gui/reason/html/app/view/CellView.js
@@ -51,6 +51,7 @@
         stripeRows: false,
         disableSelection: true,
         trackOver: false,
+        enableTextSelection: true,
     },
     features: [{
         ftype: 'rowbody',



https://bitbucket.org/yt_analysis/yt/changeset/dacb24d0c850/
changeset:   dacb24d0c850
branch:      yt
user:        MatthewTurk
date:        2012-06-14 20:30:27
summary:     Adding auto-keymap application.
affected #:  3 files

diff -r 564843888d106893768aa35835225ab2ac1c5dd8 -r dacb24d0c850a77c2868c5694f3006f68dfd78d4 yt/gui/reason/html/app/controller/widgets/BaseWidget.js
--- a/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
+++ b/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
@@ -33,6 +33,7 @@
     templates: {},
     executionTriggers: [],
     widgetTriggers: [],
+    keyTriggers: [],
 
     constructor: function() {
         this.templateManager = Ext.create(
@@ -79,6 +80,25 @@
             conf[trigger[1]] = this[trigger[2]];
             ww.query(trigger[0])[0].on(conf);
         }, this);
+
+        this.keyMap = new Ext.util.KeyMap({target: document});
+        this.keyMap.disable();
+        Ext.each(this.keyTriggers,  function(trigger) {
+            trigger['fn'] = this.getExecuteFunction(ww, trigger['tpl']);
+            this.keyMap.addBinding(trigger);
+        }, this);
+        ww.on("activate", this.activateKeyMap, this);
+        ww.on("deactivate", this.deactivateKeyMap, this);
+    },
+
+    activateKeyMap: function() {
+        console.log("Activating key map.");
+        this.keyMap.enable();
+    },
+
+    deactivateKeyMap: function() {
+        console.log("Deactivating key map.");
+        this.keyMap.disable();
     },
 
     createMyRefs: function(varname) {


diff -r 564843888d106893768aa35835225ab2ac1c5dd8 -r dacb24d0c850a77c2868c5694f3006f68dfd78d4 yt/gui/reason/html/app/controller/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
@@ -45,11 +45,11 @@
         fieldChange: 'widget_store["{widget.varname}"].set_current_field("{a1}")',
         singleUpArrow:    'widget_store["{widget.varname}"].pan_rel(( 0.0, -0.1))',
         singleRightArrow: 'widget_store["{widget.varname}"].pan_rel(( 0.1,  0.0))',
-        singleDownArrow:  'widget_store["{widget.varname}"].pan_rel(( 0.0   0.1))',
+        singleDownArrow:  'widget_store["{widget.varname}"].pan_rel(( 0.0,  0.1))',
         singleLeftArrow:  'widget_store["{widget.varname}"].pan_rel((-0.1,  0.0))',
         doubleUpArrow:    'widget_store["{widget.varname}"].pan_rel(( 0.0, -0.5))',
         doubleRightArrow: 'widget_store["{widget.varname}"].pan_rel(( 0.5,  0.0))',
-        doubleDownArrow:  'widget_store["{widget.varname}"].pan_rel(( 0.0   0.5))',
+        doubleDownArrow:  'widget_store["{widget.varname}"].pan_rel(( 0.0,  0.5))',
         doubleLeftArrow:  'widget_store["{widget.varname}"].pan_rel((-0.5,  0.0))',
         zoomIn10x:  'widget_store["{widget.varname}"].zoom(10.0)',
         zoomIn2x:   'widget_store["{widget.varname}"].zoom( 2.0)',
@@ -111,6 +111,21 @@
         { ref: 'ticks', selector: '#ticks'},
     ],
 
+    keyTriggers: [
+        { key: 'z', shift: false, tpl: "zoomIn2x" },
+        { key: 'Z', shift: true, tpl: "zoomIn10x" },
+        { key: 'x', shift: false, tpl: "zoomOut2x" },
+        { key: 'X', shift: true, tpl: "zoomOut10x" },
+        { key: 'k', shift: false, tpl: "singleUpArrow" },
+        { key: 'j', shift: false, tpl: "singleDownArrow" },
+        { key: 'h', shift: false, tpl: "singleLeftArrow" },
+        { key: 'l', shift: false, tpl: "singleRightArrow" },
+        { key: 'K', shift: true, tpl: "doubleUpArrow" },
+        { key: 'J', shift: true, tpl: "doubleDownArrow" },
+        { key: 'H', shift: true, tpl: "doubleLeftArrow" },
+        { key: 'L', shift: true, tpl: "doubleRightArrow" },
+    ],
+
     applyPayload: function(payload) {
         this.getImage().getEl("img").dom.src = 
             "data:image/png;base64," + payload['image_data'];


diff -r 564843888d106893768aa35835225ab2ac1c5dd8 -r dacb24d0c850a77c2868c5694f3006f68dfd78d4 yt/gui/reason/html/app/view/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/view/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/view/widgets/PlotWindow.js
@@ -43,7 +43,7 @@
     items: [ 
         { xtype:'image',
           itemId: 'imagepanel',
-          src: 'nothing.png',
+          src: 'reason/resources/images/loading.png',
           x: 100,
           y: 10,
           width: 400,



https://bitbucket.org/yt_analysis/yt/changeset/e39e154d49c4/
changeset:   e39e154d49c4
branch:      yt
user:        MatthewTurk
date:        2012-06-14 21:09:56
summary:     Some fiddling around got contours and vectors to work.
affected #:  3 files

diff -r dacb24d0c850a77c2868c5694f3006f68dfd78d4 -r e39e154d49c45fc6c30824e0195f8414404b8a14 yt/gui/reason/html/app/controller/widgets/BaseWidget.js
--- a/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
+++ b/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
@@ -56,7 +56,7 @@
             });
             args['control'] = control;
             args['widget'] = ww;
-            examine = {args:args, arg2: arguments};
+            examine = {args:args, arg2: arguments, tpl:tpl};
             if((isValidFn != null) && (isValidFn(arguments) == false)) {return;}
             reason.server.execute(tpl.apply(args), true);
         };


diff -r dacb24d0c850a77c2868c5694f3006f68dfd78d4 -r e39e154d49c45fc6c30824e0195f8414404b8a14 yt/gui/reason/html/app/controller/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
@@ -62,11 +62,11 @@
                          'widget_store["{widget.varname}"]._current_field, ' +
                          '"{a1.data[\'field1\']}")',
         adjustContours:  'widget_store["{widget.varname}"].set_contour_info(' +
-                         '"{[control.getContourField().getValue()]}",' +
-                         ' {[control.getNcont().getValue()]},' +
-                         ' {[control.getLogit().getValue()]:capitalize})',
+                         '"{[values.control.getContourField().getValue()]}",' +
+                         ' {[values.control.getNumContours().getValue()]},' +
+                         ' {[(Ext.util.Format.capitalize(""+values.control.getLogContours().getValue()))]})',
         adjustVectors:   'widget_store["{widget.varname}"].set_vector_info(' +
-                         '{[control.getVectorSkip()]})',
+                         '{[values.control.getVectorSkip().getValue()]})',
         recenterImage:   'widget_store["{widget.varname}"].image_recenter(' +
                          '{x}, {y}, {w}, {h})',
         dragImage:       'widget_store["{widget.varname}"].pan_rel(({rel_x}, {rel_y}))',
@@ -106,9 +106,12 @@
         { ref: 'fieldSelector', selector: '#fieldSelector'},
         { ref: 'transform', selector: '#transform'},
         { ref: 'contourField', selector: '#contourfield'},
+        { ref: 'numContours', selector: '#ncont'},
+        { ref: 'logContours', selector: '#logit'},
         { ref: 'zoomSlider', selector: '#zoomSlider'},
         { ref: 'metadataString', selector: '#metadataString'},
         { ref: 'ticks', selector: '#ticks'},
+        { ref: 'vectorSkip', selector: '#skip'},
     ],
 
     keyTriggers: [


diff -r dacb24d0c850a77c2868c5694f3006f68dfd78d4 -r e39e154d49c45fc6c30824e0195f8414404b8a14 yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -34,6 +34,7 @@
     FixedResolutionBuffer
 from .plot_modifications import get_smallest_appropriate_unit
 from .tick_locators import LogLocator, LinearLocator
+from yt.utilities.delaunay.triangulate import Triangulation as triang
 
 from yt.funcs import *
 from yt.utilities.amr_utils import write_png_to_string
@@ -419,7 +420,6 @@
         from matplotlib.figure import Figure
         from yt.visualization._mpl_imports import \
             FigureCanvasAgg, FigureCanvasPdf, FigureCanvasPS
-        from yt.utilities.delaunay.triangulate import Triangulation as triang
 
         vi, vj, vn = img.shape
 



https://bitbucket.org/yt_analysis/yt/changeset/701fcf8011ae/
changeset:   701fcf8011ae
branch:      yt
user:        MatthewTurk
date:        2012-06-15 00:05:47
summary:     I think the PlotWindow is now fully functional.
affected #:  3 files

diff -r e39e154d49c45fc6c30824e0195f8414404b8a14 -r 701fcf8011ae46e01923941588db4a7843e0f594 yt/gui/reason/html/app/controller/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
@@ -57,10 +57,10 @@
         zoomOut2x:  'widget_store["{widget.varname}"].zoom( 0.5)',
         adjustTransform: 'widget_store["{widget.varname}"].set_transform(' +
                          'widget_store["{widget.varname}"]._current_field, ' +
-                         '"{a1.data[\'field1\']}")',
+                         '"{a1}")',
         adjustColormap:  'widget_store["{widget.varname}"].set_cmap(' +
                          'widget_store["{widget.varname}"]._current_field, ' +
-                         '"{a1.data[\'field1\']}")',
+                         '"{a1}")',
         adjustContours:  'widget_store["{widget.varname}"].set_contour_info(' +
                          '"{[values.control.getContourField().getValue()]}",' +
                          ' {[values.control.getNumContours().getValue()]},' +
@@ -93,8 +93,8 @@
         ['#zoomin2x', 'click', 'zoomIn2x'],
         ['#zoomout10x', 'click', 'zoomOut10x'],
         ['#zoomout2x', 'click', 'zoomOut2x'],
-        ['#transform', 'select', 'adjustTransform'],
-        ['#colormap', 'select', 'adjustColormap'],
+        ['#transform', 'change', 'adjustTransform'],
+        ['#colormap', 'change', 'adjustColormap'],
         ['#contourapply', 'click', 'adjustContours'],
         ['#vectorsapply', 'click', 'adjustVectors'],
         ['#pannablemap', 'click', 'createPannableMap'],
@@ -130,10 +130,11 @@
     ],
 
     applyPayload: function(payload) {
-        this.getImage().getEl("img").dom.src = 
+        this.getImage().getEl().dom.src = 
             "data:image/png;base64," + payload['image_data'];
         this.getZoomSlider().setValue(0, payload['zoom'], true);
         this.getMetadataString().update(payload['metadata_string']);
+        this.getMetaDataString().mds = payload['metadata_string'];
         var ticks = this.getTicks();
         ticks.removeAll();
         Ext.each(payload['ticks'], function(tick, index) {
@@ -168,11 +169,14 @@
             {widget: this.plotWindowView}, 'refresh');
         reason.server.execute(refresh, false);
         this.getColorbar().src = "data:image/png;base64," + wd['colorbar'];
-        this.getFieldSelector().store = wd['fields'];
-        this.getFieldSelector().value = wd['initial_field'];
-        this.getTransform().value = wd['initial_transform'];
-        this.getContourField().store = wd['fields'];
-        this.getContourField().value = wd['initial_field'];
+        this.fieldStore = Ext.create("Reason.store.Fields")
+        this.fieldStore.loadData(wd['fields']);
+        examine = this.fieldStore;
+        this.getFieldSelector().bindStore(this.fieldStore);
+        this.getFieldSelector().setValue(wd['initial_field']);
+        this.getTransform().setValue(wd['initial_transform']);
+        this.getContourField().bindStore(this.fieldStore);
+        this.getContourField().setValue(wd['initial_field']);
         this.applyExecuteHandlers(this.plotWindowView);
         return this.plotWindowView;
     },
@@ -254,10 +258,10 @@
     },
 
     uploadImage: function() {
-        var imageData = this.getImage().dom.src;
-        var mds = this.getMetadataString();
+        var imageData = this.getImage().getEl().dom.src;
+        var mds = this.getMetadataString().mds;
         yt_rpc.ExtDirectREPL.upload_image(
-            {image_data:imageData, caption:metadata_string},
+            {image_data:imageData, caption:mds},
             function(rv) {
                 var alert_text;
                 if(rv['uploaded'] == false) {
@@ -266,8 +270,8 @@
                     alert_text = "Uploaded to " +
                             rv['upload']['links']['imgur_page'];
                 }
+                reason.fireEvent("logentry", alert_text);
                 Ext.Msg.alert('imgur.com', alert_text);
-                reason.fireEvent("logentry", alert_text);
             });
     },
 


diff -r e39e154d49c45fc6c30824e0195f8414404b8a14 -r 701fcf8011ae46e01923941588db4a7843e0f594 yt/gui/reason/html/app/view/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/view/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/view/widgets/PlotWindow.js
@@ -82,8 +82,7 @@
             x: 100,
             y: 435,
             width: 400,
-            store: [],
-            value: '',
+            queryMode: 'local',
             editable: false,
             triggerAction: 'all',
             validateOnBlur: false,
@@ -243,7 +242,7 @@
                        triggerAction: 'all',
                        validateOnBlur: false,
                        store: ['log10', 'linear'],
-                       value: 'linear',
+                       value: 'log10',
                      },
                      {
                        x: 10,
@@ -299,13 +298,12 @@
                        x: 80,
                        y: 20,
                        width : 160,
+                       queryMode: 'local',
                        xtype: 'combo',
                        editable: false,
                        itemId: 'contourfield',
                        triggerAction: 'all',
                        validateOnBlur: false,
-                       value: '',
-                       store: [],
                      }, {
                        x: 10,
                        y: 60,


diff -r e39e154d49c45fc6c30824e0195f8414404b8a14 -r 701fcf8011ae46e01923941588db4a7843e0f594 yt/gui/reason/widget_store.py
--- a/yt/gui/reason/widget_store.py
+++ b/yt/gui/reason/widget_store.py
@@ -64,7 +64,7 @@
         pw = PWViewerExtJS(sl, (DLE[xax], DRE[xax], DLE[yax], DRE[yax]), setup = False)
         pw.set_current_field(field)
         field_list = list(set(pf.h.field_list + pf.h.derived_field_list))
-        field_list.sort()
+        field_list = [dict(text = f) for f in sorted(field_list)]
         cb = pw._get_cbar_image()
         trans = pw._field_transform[pw._current_field].name
         widget_data = {'fields': field_list,
@@ -84,7 +84,7 @@
                            setup = False)
         pw.set_current_field(field)
         field_list = list(set(pf.h.field_list + pf.h.derived_field_list))
-        field_list.sort()
+        field_list = [dict(text = f) for f in sorted(field_list)]
         cb = pw._get_cbar_image()
         widget_data = {'fields': field_list,
                        'initial_field': field,



https://bitbucket.org/yt_analysis/yt/changeset/efea7e8f824c/
changeset:   efea7e8f824c
branch:      yt
user:        MatthewTurk
date:        2012-06-15 00:37:29
summary:     Initial translation of phase plot window and phase plot controller.
affected #:  2 files

diff -r 701fcf8011ae46e01923941588db4a7843e0f594 -r efea7e8f824cffaacbcd6757158ad409b8982612 yt/gui/reason/html/app/controller/widgets/PhasePlot.js
--- a/yt/gui/reason/html/app/controller/widgets/PhasePlot.js
+++ b/yt/gui/reason/html/app/controller/widgets/PhasePlot.js
@@ -24,166 +24,30 @@
 ***********************************************************************/
 
 
+Ext.define("Reason.controller.widgets.PhasePlot", {
+    extend: 'Reason.controller.widgets.BaseWidget',
+    requires: ['Reason.view.widgets.PhasePlot'],
 
-var WidgetPhasePlot = function(python_varname, widget_data) {
-    this.id = python_varname;
-    this.widget_data = widget_data;
-
-    viewport.get("center-panel").add(
-        {
-            xtype: 'panel',
-            id: "pp_" + this.id,
-            title: widget_data['title'],
-            iconCls: 'graph',
-            autoScroll: true,
-            layout:'absolute',
-            closable: true,
-            items: [ 
-                {
-                    xtype: 'panel',
-                    id: 'y_ticks_' + python_varname,
-                    layout: 'absolute',
-                    y: 10,
-                    x: 100,
-                    width: 40,
-                    height: 400,
-                    items : [],
-                    border: false,
-                }, {
-                    xtype: 'panel',
-                    id: 'x_ticks_' + python_varname,
-                    layout: 'absolute',
-                    y: 410,
-                    x: 140,
-                    width: 400,
-                    height: 40,
-                    items : [],
-                    border: false,
-                }, {
-                    xtype:'panel',
-                    id: 'image_panel_' + this.id,
-                    autoEl: {
-                        tag: 'img',
-                        id: "img_" + this.id,
-                        width: 400,
-                        height: 400,
-                        style: 'border: 1px solid #000000',
-                    },
-                    x: 138,
-                    y: 8,
-                    width: 400,
-                    height: 400,
-                }, {
-                    xtype:'panel',
-                    id: 'colorbar_' + python_varname,
-                    autoEl: {
-                        tag: 'img',
-                        id: "cb_" + python_varname,
-                        src: "data:image/png;base64," +
-                             widget_data['colorbar'],
-                        width: 28,
-                        height: 398,
-                        style: 'border: 1px solid #000000;',
-                    },
-                    x: 560,
-                    y: 10,
-                    width: 30,
-                    height: 400,
-                }, {
-                    xtype: 'panel',
-                    id: 'ticks_' + python_varname,
-                    layout: 'absolute',
-                    y: 10,
-                    x: 590,
-                    width: 40,
-                    height: 400,
-                    items : [],
-                    border: false,
-                },{
-                    xtype: 'button',
-                    text: 'Upload Image',
-                    x: 10,
-                    y: 285,
-                    width: 80,
-                    tooltip: "Upload the current image to " +
-                             "<a href='http://imgur.com'>imgur.com</a>",
-                    handler: function(b,e) {
-                        img_data = image_dom.src;
-                        yt_rpc.ExtDirectREPL.upload_image(
-                            {image_data:img_data,
-                             caption:metadata_string},
-                        function(rv) {
-                            var alert_text;
-                            if(rv['uploaded'] == false) {
-                                alert_text = "Failure uploading image!";
-                            } else {
-                                alert_text = "Uploaded to " +
-                                        rv['upload']['links']['imgur_page'];
-                            }
-                            Ext.Msg.alert('imgur.com', alert_text);
-                            var record = new logging_store.recordType(
-                                {record: alert_text });
-                            logging_store.add(record, number_log_records++);
-                        }); 
-                    }
-                },{
-                    xtype: 'panel',
-                    layout: 'vbox',
-                    id: 'rhs_panel_' + python_varname,
-                    width: 300,
-                    height: 460,
-                    x: 640, y: 10,
-                    layoutConfig: {
-                        align: 'stretch',
-                        pack: 'start',
-                    },
-                    items: [
-                        {
-                          xtype: 'panel',
-                          title: 'Plot MetaData',
-                          id: 'metadata_' + python_varname,
-                          style: {fontFamily: '"Inconsolata", monospace'},
-                          html: 'Welcome to the Plot Window.',
-                          height: 200,
-                        }, {
-                          xtype: 'panel',
-                          title: 'Plot Editor',
-                          id: 'plot_edit',
-                          flex: 1,
-                        }]
-                }
-            ]
-        }
-    );
-
-    viewport.get("center-panel").activate("pp_" + this.id);
-    viewport.get("center-panel").doLayout();
-    viewport.doLayout();
-    this.panel = viewport.get("center-panel").get("pp_" + python_varname);
-    this.panel.doLayout();
-    this.panel.show();
-    this.image_panel = this.panel.get("image_panel_"+python_varname);
-    this.ticks = this.panel.get("ticks_"+python_varname);
-    var x_ticks = this.panel.get("x_ticks_"+python_varname);
-    var y_ticks = this.panel.get("y_ticks_"+python_varname);
-    var ticks = this.ticks;
-    this.metadata_panel = this.panel.get("rhs_panel_" + python_varname).get("metadata_" + python_varname);
-    var image_dom = this.image_panel.el.dom;
-    var control_panel = this.panel;
-    var metadata_string;
-    var colorbar = this.panel.get("colorbar_"+python_varname);
-
-    this.accept_results = function(payload) {
-        this.image_panel.el.dom.src = "data:image/png;base64," + payload['image_data'];
-        examine = this.metadata_panel;
-        this.metadata_panel.update(payload['metadata_string']);
-        metadata_string = payload['metadata_string'];
+    viewRefs: [
+        { ref: 'yTicks', selector: '#y_ticks'},
+        { ref: 'xTicks', selector: '#x_ticks'},
+        { ref: 'colorTicks', selector: 'cb_ticks'},
+        { ref: 'colorbar', selector: '#colorbar'},
+        { ref: 'image', selector: '#imagepanel'},
+        { ref: 'metadataString', selector: '#metadataString'},
+    ],
+    
+    applyPayload: function(payload) {
+        this.getImage().getEl().dom.src = 
+            "data:image/png;base64," + payload['image_data'];
+        this.getMetadataString().update(payload['metadata_string']);
+        this.getMetaDataString().mds = payload['metadata_string'];
         ticks.removeAll();
-        colorbar.el.dom.src = "data:image/png;base64," +
-                              payload['cbar']['cmap_image'];
+        this.getColorbar.getEl().dom.src=
+            "data:image/png;base64," + payload['cbar']['cmap_image'];
+        var YTicks = this.getYTicks();
         Ext.each(payload['yax']['ticks'], function(tick, index) {
-            examine = tick;
-            y_ticks.add({xtype:'panel',
+            YTicks.add({xtype:'panel',
                        width: 20, height:15,
                        border: false,
                        style: 'font-family: "Inconsolata", monospace;' +
@@ -191,21 +55,21 @@
                               'padding-right: 5px;',
                        html: ' ' + tick[2] + ' ',
                        x:0, y: tick[0]-6});
-            y_ticks.add({xtype:'panel',
+            YTicks.add({xtype:'panel',
                        width: 20, height:1,
                        style: 'background-color: #000000;',
                        html:' ',
                        x:20, y: tick[0]});
         });
-        y_ticks.doLayout();
+        YTicks.doLayout();
+        var XTicks = this.getXTicks();
         Ext.each(payload['xax']['ticks'], function(tick, index) {
-            examine = tick;
-            x_ticks.add({xtype:'panel',
+            XTicks.add({xtype:'panel',
                        width: 1, height:20,
                        style: 'background-color: #000000;',
                        html:' ',
                        x:(400 - tick[0]) + 10, y: 0});
-            x_ticks.add({xtype:'panel',
+            XTicks.add({xtype:'panel',
                        width: 20, height:20,
                        border: false,
                        style: 'font-family: "Inconsolata", monospace;' +
@@ -213,14 +77,15 @@
                        html: ' ' + tick[2] + ' ',
                        x: (400 - tick[0]), y: 20});
         });
-        x_ticks.doLayout();
+        XTicks.doLayout();
+        var colorTicks = this.getColorTicks();
         Ext.each(payload['cbar']['ticks'], function(tick, index) {
-            ticks.add({xtype:'panel',
+            colorTicks.add({xtype:'panel',
                        width: 10, height:1,
                        style: 'background-color: #000000;',
                        html:' ',
                        x:0, y: tick[0]});
-            ticks.add({xtype:'panel',
+            colorTicks.add({xtype:'panel',
                        width: 30, height:15,
                        border: false,
                        style: 'font-family: "Inconsolata", monospace;' +
@@ -228,12 +93,80 @@
                        html: ' ' + tick[2] + ' ',
                        x:18, y: tick[0]-6});
         });
-        ticks.doLayout();
-        x_ticks.doLayout();
-    }
-    yt_rpc.ExtDirectREPL.execute(
-        {code:python_varname + '._setup_plot()', hide:true},
-        cell_finished);
-}
+        colorTicks.doLayout();
+    },
 
-widget_types['phase_plot'] = WidgetPhasePlot;
+    statics: {
+        widgetName: 'phase_plot',
+        supportsDataObjects: true,
+        supportsParameterFiles: false,
+        displayName: 'Phase Plot',
+        preCreation: function(obj) {
+            var widget = Ext.create(this.getName());
+            function makePlot(b, e) {
+                var conf = {
+                    pfname: obj.varname,
+                    axis: win.query("#axis")[0].getValue(),
+                    field: win.query("#field")[0].getValue(),
+                    onmax: "" + win.query("#maxDens")[0].getValue(),
+                };
+                var method = 'createSlice';
+                if (win.query("#plotType")[0].getValue() == 'Projection') {
+                    method = 'createProj';
+                    conf['weight'] = win.query("#weightField")[0].getValue();
+                } else {
+                  conf['center'] = [win.query("#slice_x_center")[0].getValue(),
+                                    win.query("#slice_y_center")[0].getValue(),
+                                    win.query("#slice_z_center")[0].getValue()];
+                }
+                var cmd = widget.templateManager.applyObject(conf, method);
+                reason.server.execute(cmd);
+                win.destroy();
+            }
+            function togglePlotType(b, e) {
+                var plotType = win.query("#plotType")[0].getValue();
+                examine = win;
+                if (plotType == 'Projection') {
+                    win.query("#weightField")[0].enable();
+                    win.query("#maxDens")[0].disable();
+                    win.query("#slice_x_center")[0].disable();
+                    win.query("#slice_y_center")[0].disable();
+                    win.query("#slice_z_center")[0].disable();
+                } else {
+                    win.query("#weightField")[0].disable();
+                    win.query("#maxDens")[0].enable();
+                    win.query("#slice_x_center")[0].enable();
+                    win.query("#slice_y_center")[0].enable();
+                    win.query("#slice_z_center")[0].enable();
+                }
+            }
+            function toggleMaxDens(checkbox, checked) {
+                var plotType = win.query("#plotType")[0].getValue();
+                if (plotType == "Projection") { return; }
+                if (checked == true) {
+                    win.query("#slice_x_center")[0].disable();
+                    win.query("#slice_y_center")[0].disable();
+                    win.query("#slice_z_center")[0].disable();
+                } else {
+                    win.query("#slice_x_center")[0].enable();
+                    win.query("#slice_y_center")[0].enable();
+                    win.query("#slice_z_center")[0].enable();
+                }
+            }
+            var title = widget.templateManager.applyObject(obj, 'pwt');
+            win = Ext.widget("plotwindowcreator", {title:title, obj:obj});
+            win.query("#weightField")[0].store = 
+                ['None'].concat(obj.field_list);
+            win.query("#field")[0].store = obj.field_list;
+            win.query("#create")[0].on('click', makePlot);
+            win.query("#cancel")[0].on('click', function(){win.destroy();});
+            win.query("#maxDens")[0].on('change', toggleMaxDens);
+            win.query("#plotType")[0].on('change', togglePlotType);
+            togglePlotType();
+            toggleMaxDens();
+            win.show();
+            /* Note that in this case, our instance of 'widget', which is this
+               class, is not long-lived.  It dies after the window is
+               destroyed. */
+        },
+});


diff -r 701fcf8011ae46e01923941588db4a7843e0f594 -r efea7e8f824cffaacbcd6757158ad409b8982612 yt/gui/reason/html/app/view/widgets/PhasePlot.js
--- /dev/null
+++ b/yt/gui/reason/html/app/view/widgets/PhasePlot.js
@@ -0,0 +1,122 @@
+/**********************************************************************
+The Plot Window Widget
+
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+
+Ext.define("Reason.view.widgets.PhasePlot", {
+    extend: 'Ext.panel.Panel',
+    title: 'This should not be visible.',
+    alias: 'widget.phaseplotwindow',
+    iconCls: 'graph',
+    autoScroll: true,
+    layout: 'absolute',
+    width: '100%',
+    height: '100%',
+    closable: true,
+
+    items: [
+        {
+            xtype: 'panel',
+            itemId: 'y_ticks',
+            layout: 'absolute',
+            y: 10,
+            x: 100,
+            width: 40,
+            height: 400,
+            items : [],
+            border: false,
+        }, {
+            xtype: 'panel',
+            itemId: 'x_ticks',
+            layout: 'absolute',
+            y: 410,
+            x: 140,
+            width: 400,
+            height: 40,
+            items : [],
+            border: false,
+        }, {
+            xtype:'image',
+            itemId: 'imagepanel',
+            src: 'reason/resources/images/loading.png',
+            style: 'border: 1px solid #000000;',
+            x: 138,
+            y: 8,
+            width: 400,
+            height: 400,
+        }, {
+            xtype:'image',
+            itemId: 'colorbar',
+            style: 'border: 1px solid #000000;',
+            x: 560,
+            y: 10,
+            width: 30,
+            height: 400,
+        }, {
+            xtype: 'panel',
+            itemId: 'cb_ticks',
+            layout: 'absolute',
+            y: 10,
+            x: 590,
+            width: 40,
+            height: 400,
+            items : [],
+            border: false,
+        },{
+            xtype: 'button',
+            text: 'Upload Image',
+            itemId: 'uploadimage',
+            x: 10,
+            y: 285,
+            width: 80,
+            tooltip: "Upload the current image to " +
+                     "<a href='http://imgur.com'>imgur.com</a>",
+        },{
+            xtype: 'panel',
+            layout: 'vbox',
+            itemId: 'rhs_panel',
+            width: 300,
+            height: 460,
+            x: 640, y: 10,
+            layoutConfig: {
+                align: 'stretch',
+                pack: 'start',
+            },
+            items: [
+                {
+                  xtype: 'panel',
+                  title: 'Plot MetaData',
+                  itemId: 'metadataString',
+                  style: {fontFamily: '"Inconsolata", monospace'},
+                  html: 'Welcome to the Plot Window.',
+                  height: 200,
+                }, {
+                  xtype: 'panel',
+                  title: 'Plot Editor',
+                  itemId: 'plot_edit',
+                  flex: 1,
+                }]
+        }
+    ],
+});



https://bitbucket.org/yt_analysis/yt/changeset/daff6a807d7e/
changeset:   daff6a807d7e
branch:      yt
user:        MatthewTurk
date:        2012-06-15 01:49:36
summary:     All but the Python side for the phase plot.  Fixed the data object / parameter
file issue in the data object tree.
affected #:  5 files

diff -r efea7e8f824cffaacbcd6757158ad409b8982612 -r daff6a807d7edec3adf47f09be99b4d8bfa823b0 yt/gui/reason/extdirect_repl.py
--- a/yt/gui/reason/extdirect_repl.py
+++ b/yt/gui/reason/extdirect_repl.py
@@ -473,11 +473,10 @@
         for fn, pf in sorted(_cached_pfs.items()):
             objs = []
             pf_varname = "_cached_pfs['%s']" % (fn)
-            fields = []
+            field_list = []
             if pf._instantiated_hierarchy is not None: 
-                fields = set(pf.h.field_list + pf.h.derived_field_list)
-                fields = list(fields)
-                fields.sort()
+                field_list = list(set(pf.h.field_list + pf.h.derived_field_list))
+                field_list = [dict(text = f) for f in sorted(field_list)]
                 for i,obj in enumerate(pf.h.objects):
                     try:
                         name = str(obj)
@@ -488,7 +487,7 @@
                                      varname = "%s.h.objects[%s]" % (pf_varname, i)))
             rv.append( dict(name = str(pf), children = objs, filename=fn,
                             type = "parameter_file",
-                            varname = pf_varname, field_list = fields) )
+                            varname = pf_varname, field_list = field_list) )
         return rv
 
 def ext_load_script(filename):


diff -r efea7e8f824cffaacbcd6757158ad409b8982612 -r daff6a807d7edec3adf47f09be99b4d8bfa823b0 yt/gui/reason/html/app/controller/DataObjects.js
--- a/yt/gui/reason/html/app/controller/DataObjects.js
+++ b/yt/gui/reason/html/app/controller/DataObjects.js
@@ -76,11 +76,11 @@
             });
             Ext.each(o['children'], function(c, ci, cs) {
                 /*console.log("    Appending " + c['name']);*/
-                pf.appendChild({name: o.name,
-                                type: o.type,
+                pf.appendChild({name: c.name,
+                                type: c.type,
                                 filename: o.filename,
                                 field_list: o.field_list,
-                                varname: o.varname,
+                                varname: c.varname,
                                 leaf: true,
                                 iconcls: 'data_obj'});
 


diff -r efea7e8f824cffaacbcd6757158ad409b8982612 -r daff6a807d7edec3adf47f09be99b4d8bfa823b0 yt/gui/reason/html/app/controller/WidgetDirector.js
--- a/yt/gui/reason/html/app/controller/WidgetDirector.js
+++ b/yt/gui/reason/html/app/controller/WidgetDirector.js
@@ -31,6 +31,7 @@
                "Reason.controller.widgets.GridDataViewer",
                "Reason.controller.widgets.ParameterFile",
                "Reason.controller.widgets.PannableMap",
+               "Reason.controller.widgets.PhasePlot",
     ],
     stores: ['WidgetTypes', 'WidgetInstances'],
     views: ['WidgetTypesGrid', 'WidgetInstancesGrid'],
@@ -70,6 +71,7 @@
 
     showWidgetMenu: function(treerecord, e) {
         var contextMenu = Ext.create('Ext.menu.Menu', {plain: true,});
+        examine = treerecord;
         var data = treerecord.data;
         var w;
         this.getWidgetTypesStore().each(function(record, idx) {


diff -r efea7e8f824cffaacbcd6757158ad409b8982612 -r daff6a807d7edec3adf47f09be99b4d8bfa823b0 yt/gui/reason/html/app/controller/widgets/PhasePlot.js
--- a/yt/gui/reason/html/app/controller/widgets/PhasePlot.js
+++ b/yt/gui/reason/html/app/controller/widgets/PhasePlot.js
@@ -26,7 +26,11 @@
 
 Ext.define("Reason.controller.widgets.PhasePlot", {
     extend: 'Reason.controller.widgets.BaseWidget',
-    requires: ['Reason.view.widgets.PhasePlot'],
+    requires: ['Reason.view.widgets.PhasePlotCreator',
+               'Reason.view.widgets.PhasePlot'],
+    templates: {
+        createPhasePlot: "print 1",
+    },
 
     viewRefs: [
         { ref: 'yTicks', selector: '#y_ticks'},
@@ -103,70 +107,43 @@
         displayName: 'Phase Plot',
         preCreation: function(obj) {
             var widget = Ext.create(this.getName());
+            examine = obj;
             function makePlot(b, e) {
                 var conf = {
                     pfname: obj.varname,
-                    axis: win.query("#axis")[0].getValue(),
-                    field: win.query("#field")[0].getValue(),
-                    onmax: "" + win.query("#maxDens")[0].getValue(),
+                    xField: win.query("#x_field")[0].getValue(),
+                    yfield: win.query("#y_field")[0].getValue(),
+                    zfield: win.query("#z_field")[0].getValue(),
                 };
-                var method = 'createSlice';
-                if (win.query("#plotType")[0].getValue() == 'Projection') {
-                    method = 'createProj';
-                    conf['weight'] = win.query("#weightField")[0].getValue();
-                } else {
-                  conf['center'] = [win.query("#slice_x_center")[0].getValue(),
-                                    win.query("#slice_y_center")[0].getValue(),
-                                    win.query("#slice_z_center")[0].getValue()];
+                var weight = win.query("#weight")[0].getValue();
+                if (weight == 'Mass') {
+                    weightField = '"CellMassMsun"';
+                } else if (weight == 'Volume') {
+                    weightField = '"CellVolume"';
+                } else if (weight == 'Just Sum') {
+                    weightField = 'None';
                 }
-                var cmd = widget.templateManager.applyObject(conf, method);
+                conf['weight'] = weightField;
+                var cmd = widget.templateManager.applyObject(
+                    conf, 'createPhasePlot');
                 reason.server.execute(cmd);
                 win.destroy();
             }
-            function togglePlotType(b, e) {
-                var plotType = win.query("#plotType")[0].getValue();
-                examine = win;
-                if (plotType == 'Projection') {
-                    win.query("#weightField")[0].enable();
-                    win.query("#maxDens")[0].disable();
-                    win.query("#slice_x_center")[0].disable();
-                    win.query("#slice_y_center")[0].disable();
-                    win.query("#slice_z_center")[0].disable();
-                } else {
-                    win.query("#weightField")[0].disable();
-                    win.query("#maxDens")[0].enable();
-                    win.query("#slice_x_center")[0].enable();
-                    win.query("#slice_y_center")[0].enable();
-                    win.query("#slice_z_center")[0].enable();
-                }
-            }
-            function toggleMaxDens(checkbox, checked) {
-                var plotType = win.query("#plotType")[0].getValue();
-                if (plotType == "Projection") { return; }
-                if (checked == true) {
-                    win.query("#slice_x_center")[0].disable();
-                    win.query("#slice_y_center")[0].disable();
-                    win.query("#slice_z_center")[0].disable();
-                } else {
-                    win.query("#slice_x_center")[0].enable();
-                    win.query("#slice_y_center")[0].enable();
-                    win.query("#slice_z_center")[0].enable();
-                }
-            }
-            var title = widget.templateManager.applyObject(obj, 'pwt');
-            win = Ext.widget("plotwindowcreator", {title:title, obj:obj});
-            win.query("#weightField")[0].store = 
-                ['None'].concat(obj.field_list);
-            win.query("#field")[0].store = obj.field_list;
+            win = Ext.widget("phaseplotcreator", {obj:obj});
+            var xFieldObj = win.query("#x_field")[0];
+            var yFieldObj = win.query("#y_field")[0];
+            var zFieldObj = win.query("#z_field")[0];
+            this.fieldStore = Ext.create("Reason.store.Fields");
+            this.fieldStore.loadData(obj.field_list);
+            xFieldObj.bindStore(this.fieldStore);
+            yFieldObj.bindStore(this.fieldStore);
+            zFieldObj.bindStore(this.fieldStore);
+            xFieldObj.setValue("Density");
+            yFieldObj.setValue("Temperature");
+            zFieldObj.setValue("CellMassMsun");
             win.query("#create")[0].on('click', makePlot);
             win.query("#cancel")[0].on('click', function(){win.destroy();});
-            win.query("#maxDens")[0].on('change', toggleMaxDens);
-            win.query("#plotType")[0].on('change', togglePlotType);
-            togglePlotType();
-            toggleMaxDens();
             win.show();
-            /* Note that in this case, our instance of 'widget', which is this
-               class, is not long-lived.  It dies after the window is
-               destroyed. */
         },
+    },
 });


diff -r efea7e8f824cffaacbcd6757158ad409b8982612 -r daff6a807d7edec3adf47f09be99b4d8bfa823b0 yt/gui/reason/html/app/view/widgets/PhasePlotCreator.js
--- /dev/null
+++ b/yt/gui/reason/html/app/view/widgets/PhasePlotCreator.js
@@ -0,0 +1,96 @@
+/**********************************************************************
+The Phase Plot Creator
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define("Reason.view.widgets.PhasePlotCreator", {
+    extend: 'Ext.window.Window',
+    alias: 'widget.phaseplotcreator',
+    width: 370,
+    height: 200,
+    modal: true,
+    resizable: false,
+    draggable: false,
+    border: false,
+    layout: 'fit',
+    title: "Create Phase Plot",
+
+    items: [{ xtype: 'form', // FormPanel
+              labelWidth:80,
+              frame:true,
+              items: [ {
+                xtype:'combo',
+                fieldLabel: 'X Field',
+                id: 'x_field',
+                width: 350,
+                queryMode: 'local',
+                editable: false,
+                triggerAction: 'all',
+                value: 'Density'
+            },{
+                xtype:'combo',
+                fieldLabel: 'Y Field',
+                id: 'y_field',
+                width: 350,
+                queryMode: 'local',
+                editable: false,
+                triggerAction: 'all',
+                value: 'Density'
+            },{
+                xtype:'combo',
+                fieldLabel: 'Z Field',
+                id: 'z_field',
+                width: 350,
+                queryMode: 'local',
+                editable: false,
+                triggerAction: 'all',
+                value: 'Density'
+            },{
+                xtype:'combo',
+                fieldLabel: 'Weight by',
+                id: 'weight',
+                width: 350,
+                allowBlank:false,
+                triggerAction: 'all',
+                value: 'Just Sum',
+                queryMode: 'local',
+                store: ['Just Sum', 'Mass', 'Volume'],
+            }],
+            buttons: [
+                {
+                    text: 'Calculate',
+                    itemId: 'create',
+                },{
+                    text: 'Cancel',
+                    itemId: 'cancel',
+                }
+            ]
+        }],
+});
+



https://bitbucket.org/yt_analysis/yt/changeset/21159c955172/
changeset:   21159c955172
branch:      yt
user:        MatthewTurk
date:        2012-06-15 02:15:46
summary:     Phase plot now creates correctly.
affected #:  4 files

diff -r daff6a807d7edec3adf47f09be99b4d8bfa823b0 -r 21159c955172ace3dade09ade64f72c6e976e705 yt/gui/reason/extdirect_repl.py
--- a/yt/gui/reason/extdirect_repl.py
+++ b/yt/gui/reason/extdirect_repl.py
@@ -421,45 +421,6 @@
             results.append((os.path.basename(fn), size, t))
         return dict(objs = results, cur_dir=cur_dir)
 
-    @lockit
-    def create_phase(self, objname, field_x, field_y, field_z, weight):
-        if weight == "None": weight = None
-        else: weight = "'%s'" % (weight)
-        funccall = """
-        _tfield_x = "%(field_x)s"
-        _tfield_y = "%(field_y)s"
-        _tfield_z = "%(field_z)s"
-        _tweight = %(weight)s
-        _tobj = %(objname)s
-        _tpf = _tobj.pf
-        from yt.visualization.profile_plotter import PhasePlotterExtWidget
-        _tpp = PhasePlotterExtWidget(_tobj, _tfield_x, _tfield_y, _tfield_z, _tweight)
-        _tfield_list = list(set(_tpf.h.field_list + _tpf.h.derived_field_list))
-        _tfield_list.sort()
-        _twidget_data = {'title': "%%s Phase Plot" %% (_tobj)}
-        """ % dict(objname = objname, field_x = field_x, field_y = field_y,
-                   field_z = field_z, weight = weight)
-        funccall = "\n".join(line.strip() for line in funccall.splitlines())
-        self.execute(funccall, hide=True)
-        self.execution_thread.queue.put({'type': 'add_widget',
-                                         'name': '_tpp',
-                                         'widget_data_name': '_twidget_data'})
-
-    @lockit
-    def create_mapview(self, widget_name):
-        # We want multiple maps simultaneously
-        uu = "/%s/%s" % (getattr(self, "_global_token", ""),
-                        str(uuid.uuid1()).replace("-","_"))
-        from .pannable_map import PannableMapServer
-        data = self.locals[widget_name].data_source
-        field_name = self.locals[widget_name]._current_field
-        pm = PannableMapServer(data, field_name, route_prefix = uu)
-        self.locals['_tpm'] = pm
-        self.locals['_twidget_data'] = {'prefix': uu, 'field':field_name}
-        self.execution_thread.queue.put({'type': 'add_widget',
-                                         'name': '_tpm',
-                                         'widget_data_name': '_twidget_data'})
-
 class ExtDirectParameterFileList(BottleDirectRouter):
     my_name = "ExtDirectParameterFileList"
     api_url = "pflist"


diff -r daff6a807d7edec3adf47f09be99b4d8bfa823b0 -r 21159c955172ace3dade09ade64f72c6e976e705 yt/gui/reason/html/app/controller/widgets/PhasePlot.js
--- a/yt/gui/reason/html/app/controller/widgets/PhasePlot.js
+++ b/yt/gui/reason/html/app/controller/widgets/PhasePlot.js
@@ -29,27 +29,34 @@
     requires: ['Reason.view.widgets.PhasePlotCreator',
                'Reason.view.widgets.PhasePlot'],
     templates: {
-        createPhasePlot: "print 1",
+        createPhasePlot: 'widget_store.create_phase({objname}, ' + 
+                         '"{xField}", "{yField}", "{zField}", {weight})',
+        setupPlot:       'widget_store["{widget.varname}"]._setup_plot()',
     },
 
+    executionTriggers: [
+        ['#imagepanel', 'afterrender', 'setupPlot'],
+    ],
+
     viewRefs: [
         { ref: 'yTicks', selector: '#y_ticks'},
         { ref: 'xTicks', selector: '#x_ticks'},
-        { ref: 'colorTicks', selector: 'cb_ticks'},
+        { ref: 'colorTicks', selector: '#cb_ticks'},
         { ref: 'colorbar', selector: '#colorbar'},
         { ref: 'image', selector: '#imagepanel'},
         { ref: 'metadataString', selector: '#metadataString'},
     ],
     
     applyPayload: function(payload) {
+        examine = payload;
         this.getImage().getEl().dom.src = 
             "data:image/png;base64," + payload['image_data'];
         this.getMetadataString().update(payload['metadata_string']);
-        this.getMetaDataString().mds = payload['metadata_string'];
-        ticks.removeAll();
-        this.getColorbar.getEl().dom.src=
+        this.getMetadataString().mds = payload['metadata_string'];
+        this.getColorbar().getEl().dom.src=
             "data:image/png;base64," + payload['cbar']['cmap_image'];
         var YTicks = this.getYTicks();
+        YTicks.removeAll();
         Ext.each(payload['yax']['ticks'], function(tick, index) {
             YTicks.add({xtype:'panel',
                        width: 20, height:15,
@@ -67,6 +74,7 @@
         });
         YTicks.doLayout();
         var XTicks = this.getXTicks();
+        XTicks.removeAll();
         Ext.each(payload['xax']['ticks'], function(tick, index) {
             XTicks.add({xtype:'panel',
                        width: 1, height:20,
@@ -83,6 +91,7 @@
         });
         XTicks.doLayout();
         var colorTicks = this.getColorTicks();
+        colorTicks.removeAll();
         Ext.each(payload['cbar']['ticks'], function(tick, index) {
             colorTicks.add({xtype:'panel',
                        width: 10, height:1,
@@ -100,6 +109,17 @@
         colorTicks.doLayout();
     },
 
+    createView: function() {
+        var wd = this.payload['data'];
+        this.dataView = Ext.widget("phaseplotwindow",{
+            varname : this.payload['varname'],
+            title: wd['title'],
+        });
+        this.createMyRefs(this.dataView.id);
+        this.applyExecuteHandlers(this.dataView);
+        return this.dataView;
+    },
+
     statics: {
         widgetName: 'phase_plot',
         supportsDataObjects: true,
@@ -110,10 +130,10 @@
             examine = obj;
             function makePlot(b, e) {
                 var conf = {
-                    pfname: obj.varname,
+                    objname: obj.varname,
                     xField: win.query("#x_field")[0].getValue(),
-                    yfield: win.query("#y_field")[0].getValue(),
-                    zfield: win.query("#z_field")[0].getValue(),
+                    yField: win.query("#y_field")[0].getValue(),
+                    zField: win.query("#z_field")[0].getValue(),
                 };
                 var weight = win.query("#weight")[0].getValue();
                 if (weight == 'Mass') {
@@ -124,6 +144,7 @@
                     weightField = 'None';
                 }
                 conf['weight'] = weightField;
+                examine = {conf: conf, widget: widget};
                 var cmd = widget.templateManager.applyObject(
                     conf, 'createPhasePlot');
                 reason.server.execute(cmd);


diff -r daff6a807d7edec3adf47f09be99b4d8bfa823b0 -r 21159c955172ace3dade09ade64f72c6e976e705 yt/gui/reason/html/app/view/widgets/PhasePlot.js
--- a/yt/gui/reason/html/app/view/widgets/PhasePlot.js
+++ b/yt/gui/reason/html/app/view/widgets/PhasePlot.js
@@ -100,6 +100,7 @@
             height: 460,
             x: 640, y: 10,
             layoutConfig: {
+                type: 'vbox',
                 align: 'stretch',
                 pack: 'start',
             },


diff -r daff6a807d7edec3adf47f09be99b4d8bfa823b0 -r 21159c955172ace3dade09ade64f72c6e976e705 yt/gui/reason/widget_store.py
--- a/yt/gui/reason/widget_store.py
+++ b/yt/gui/reason/widget_store.py
@@ -137,6 +137,14 @@
         widget_data = {'prefix': uu, 'field':field_name}
         self._add_widget(pm, widget_data)
 
+    def create_phase(self, obj, field_x, field_y, field_z, weight):
+        if weight == "None": weight = None
+        else: weight = "'%s'" % (weight)
+        from yt.visualization.profile_plotter import PhasePlotterExtWidget
+        pp = PhasePlotterExtWidget(obj, field_x, field_y, field_z, weight)
+        widget_data = {'title': "%s Phase Plot" % (obj)}
+        self._add_widget(pp, widget_data)
+
 class ParameterFileWidget(object):
     _ext_widget_id = None
     _widget_name = "parameterfile"



https://bitbucket.org/yt_analysis/yt/changeset/670d0be0e01b/
changeset:   670d0be0e01b
branch:      yt
user:        MatthewTurk
date:        2012-06-15 02:33:13
summary:     Phase plots are finished.
affected #:  4 files

diff -r 21159c955172ace3dade09ade64f72c6e976e705 -r 670d0be0e01bfe3d6d57790c5fd9647d1378f454 yt/gui/reason/html/app/controller/widgets/PhasePlot.js
--- a/yt/gui/reason/html/app/controller/widgets/PhasePlot.js
+++ b/yt/gui/reason/html/app/controller/widgets/PhasePlot.js
@@ -51,8 +51,6 @@
         examine = payload;
         this.getImage().getEl().dom.src = 
             "data:image/png;base64," + payload['image_data'];
-        this.getMetadataString().update(payload['metadata_string']);
-        this.getMetadataString().mds = payload['metadata_string'];
         this.getColorbar().getEl().dom.src=
             "data:image/png;base64," + payload['cbar']['cmap_image'];
         var YTicks = this.getYTicks();
@@ -117,6 +115,8 @@
         });
         this.createMyRefs(this.dataView.id);
         this.applyExecuteHandlers(this.dataView);
+        this.getMetadataString().update(this.payload['data']['metadata_string']);
+        this.getMetadataString().mds = this.payload['data']['metadata_string'];
         return this.dataView;
     },
 


diff -r 21159c955172ace3dade09ade64f72c6e976e705 -r 670d0be0e01bfe3d6d57790c5fd9647d1378f454 yt/gui/reason/html/app/view/widgets/PhasePlot.js
--- a/yt/gui/reason/html/app/view/widgets/PhasePlot.js
+++ b/yt/gui/reason/html/app/view/widgets/PhasePlot.js
@@ -99,11 +99,7 @@
             width: 300,
             height: 460,
             x: 640, y: 10,
-            layoutConfig: {
-                type: 'vbox',
-                align: 'stretch',
-                pack: 'start',
-            },
+            layout: 'absolute',
             items: [
                 {
                   xtype: 'panel',
@@ -112,12 +108,19 @@
                   style: {fontFamily: '"Inconsolata", monospace'},
                   html: 'Welcome to the Plot Window.',
                   height: 200,
+                  width: 300,
+                  x: 0,
+                  y: 0,
                 }, {
                   xtype: 'panel',
                   title: 'Plot Editor',
                   itemId: 'plot_edit',
-                  flex: 1,
-                }]
+                  height: 460,
+                  width: 300,
+                  x: 0,
+                  y: 200,
+                },
+           ],
         }
     ],
 });


diff -r 21159c955172ace3dade09ade64f72c6e976e705 -r 670d0be0e01bfe3d6d57790c5fd9647d1378f454 yt/gui/reason/widget_store.py
--- a/yt/gui/reason/widget_store.py
+++ b/yt/gui/reason/widget_store.py
@@ -29,6 +29,14 @@
 from yt.visualization.plot_window import PWViewerExtJS
 import uuid
 
+_phase_plot_mds = """<pre>
+Field X: %s
+Field Y: %s
+Field Z: %s
+Weight : %s
+</pre>
+"""
+
 class WidgetStore(dict):
     def __init__(self, repl):
         self.repl = weakref.proxy(repl)
@@ -138,11 +146,12 @@
         self._add_widget(pm, widget_data)
 
     def create_phase(self, obj, field_x, field_y, field_z, weight):
-        if weight == "None": weight = None
-        else: weight = "'%s'" % (weight)
         from yt.visualization.profile_plotter import PhasePlotterExtWidget
         pp = PhasePlotterExtWidget(obj, field_x, field_y, field_z, weight)
-        widget_data = {'title': "%s Phase Plot" % (obj)}
+        mds = _phase_plot_mds % (field_x, field_y, field_z, 
+                                 pp._initial_weight)
+        widget_data = {'title': "%s Phase Plot" % (obj),
+                       'metadata_string': mds}
         self._add_widget(pp, widget_data)
 
 class ParameterFileWidget(object):


diff -r 21159c955172ace3dade09ade64f72c6e976e705 -r 670d0be0e01bfe3d6d57790c5fd9647d1378f454 yt/visualization/profile_plotter.py
--- a/yt/visualization/profile_plotter.py
+++ b/yt/visualization/profile_plotter.py
@@ -277,6 +277,7 @@
            field_z.startswith("CellVolume"):
             mylog.warning("Setting weight to None")
             weight = None
+        self._initial_weight = weight
         profile.add_fields(field_z, weight=weight, accumulation=accumulation, fractional=fractional)
         self._current_field = field_z
         self.profile = profile



https://bitbucket.org/yt_analysis/yt/changeset/471a44f99c04/
changeset:   471a44f99c04
branch:      yt
user:        MatthewTurk
date:        2012-06-15 02:38:39
summary:     Adding ExtJS 4.1 to the install script, but not unzipping it.
affected #:  1 file

diff -r 670d0be0e01bfe3d6d57790c5fd9647d1378f454 -r 471a44f99c0452428e3800d0234e8dd12566e668 doc/install_script.sh
--- a/doc/install_script.sh
+++ b/doc/install_script.sh
@@ -358,8 +358,7 @@
 echo '44eea803870a66ff0bab08d13a8b3388b5578ebc1c807d1d9dca0a93e6371e91b15d02917a00b3b20dc67abb5a21dabaf9b6e9257a561f85eeff2147ac73b478  PyX-0.11.1.tar.gz' > PyX-0.11.1.tar.gz.sha512
 echo '1a754d560bfa433f0960ab3b5a62edb5f291be98ec48cf4e5941fa5b84139e200b87a52efbbd6fa4a76d6feeff12439eed3e7a84db4421940d1bbb576f7a684e  Python-2.7.2.tgz' > Python-2.7.2.tgz.sha512
 echo 'c017d3d59dd324ac91af0edc178c76b60a5f90fbb775cf843e39062f95bd846238f2c53705f8890ed3f34bc0e6e75671a73d13875eb0287d6201cb45f0a2d338  bzip2-1.0.5.tar.gz' > bzip2-1.0.5.tar.gz.sha512
-echo 'de73b14727c2a6623c19896d4c034ad0f705bf5ccbb8501c786a9d074cce97a7760db9246ae7da3db47dd2de29a1707a8a0ee17ab41a6d9140f2a7dbf455af0f  ext-3.3.2.zip' > ext-3.3.2.zip.sha512
-echo '6d65dcbb77978d4f4a9711062f11ae9d61133ca086f9207a8c1ecea8807dc9612cc8c3b2428157d2fb00dea8e0958f61e35cce4e07987c80bc808bbda3608a6c  ext-slate-110328.zip' > ext-slate-110328.zip.sha512
+echo '445de41f63a03bf1c098e36b5658590d8837a80ecd3ce8ff6544d30653cc64ce2521e6354016ca3b56a35a8416c33567506db8acec29ea3d9d97ae5f2e7eca02  ext-4.1.0-gpl.zip' > ext-4.1.0-gpl.zip.sha512
 echo 'b519218f93946400326e9b656669269ecb3e5232b944e18fbc3eadc4fe2b56244d68aae56d6f69042b4c87c58c881ee2aaa279561ea0f0f48d5842155f4de9de  freetype-2.4.4.tar.gz' > freetype-2.4.4.tar.gz.sha512
 echo '1531789e0a77d4829796d18552a4de7aecae7e8b63763a7951a8091921995800740fe03e72a7dbd496a5590828131c5f046ddead695e5cba79343b8c205148d1  h5py-2.0.1.tar.gz' > h5py-2.0.1.tar.gz.sha512
 echo '9644896e4a84665ad22f87eb885cbd4a0c60a5c30085d5dd5dba5f3c148dbee626f0cb01e59a7995a84245448a3f1e9ba98687d3f10250e2ee763074ed8ddc0e  hdf5-1.8.7.tar.gz' > hdf5-1.8.7.tar.gz.sha512
@@ -392,9 +391,7 @@
 get_enzotools ipython-0.12.tar.gz
 get_enzotools h5py-2.0.1.tar.gz
 get_enzotools Cython-0.16.tar.gz
-get_enzotools ext-3.3.2.zip
-get_enzotools ext-slate-110328.zip
-get_enzotools PhiloGL-1.4.2.zip
+get_enzotools ext-4.1.0-gpl.zip
 
 if [ $INST_BZLIB -eq 1 ]
 then
@@ -661,36 +658,6 @@
     cd $MY_PWD
 fi
 
-# Now we open up the ext repository
-if [ ! -e ext-3.3.2/done ]
-then
-    ( unzip -o ext-3.3.2.zip 2>&1 ) 1>> ${LOG_FILE} || do_exit
-    ( echo "Symlinking ext-3.3.2 as ext-resources" 2>&1 ) 1>> ${LOG_FILE}
-    rm -rf ext-resources
-    ln -sf ext-3.3.2 ext-resources
-    touch ext-3.3.2/done
-fi
-
-# Now we open up the ext theme
-if [ ! -e ext-slate-110328/done ]
-then
-    ( unzip -o ext-slate-110328.zip 2>&1 ) 1>> ${LOG_FILE} || do_exit
-    ( echo "Symlinking ext-slate-110328 as ext-theme" 2>&1 ) 1>> ${LOG_FILE}
-    rm -rf ext-theme
-    ln -sf ext-slate-110328 ext-theme
-    touch ext-slate-110328/done
-fi
-
-# Now we open up PhiloGL
-if [ ! -e PhiloGL-1.4.2/done ]
-then
-    ( unzip -o PhiloGL-1.4.2.zip 2>&1 ) 1>> ${LOG_FILE} || do_exit
-    ( echo "Symlinking PhiloGL-1.4.2 as PhiloGL" 2>&1 ) 1>> ${LOG_FILE}
-    rm -rf PhiloGL
-    ln -sf PhiloGL-1.4.2 PhiloGL
-    touch PhiloGL-1.4.2/done
-fi
-
 if [ -e $HOME/.matplotlib/fontList.cache ] && \
    ( grep -q python2.6 $HOME/.matplotlib/fontList.cache )
 then



https://bitbucket.org/yt_analysis/yt/changeset/fd793137ae83/
changeset:   fd793137ae83
branch:      yt
user:        MatthewTurk
date:        2012-06-15 15:47:02
summary:     Ported the file open dialog.
affected #:  6 files

diff -r 471a44f99c0452428e3800d0234e8dd12566e668 -r fd793137ae83b7ed58ad6e1181b5c991a5cdd3eb yt/gui/reason/html/app.js
--- a/yt/gui/reason/html/app.js
+++ b/yt/gui/reason/html/app.js
@@ -106,6 +106,7 @@
         'WidgetDirector',
         'MenuActions',
         'Debugger',
+        'FileOpen',
     ],
 
 });


diff -r 471a44f99c0452428e3800d0234e8dd12566e668 -r fd793137ae83b7ed58ad6e1181b5c991a5cdd3eb yt/gui/reason/html/app/controller/FileOpen.js
--- /dev/null
+++ b/yt/gui/reason/html/app/controller/FileOpen.js
@@ -0,0 +1,107 @@
+/**********************************************************************
+File Open Dialog for Reason
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define('Reason.controller.FileOpen', {
+    extend: 'Ext.app.Controller',
+    stores: ['FileListing'],
+    requires: ["Reason.view.FileOpen"],
+    
+    init: function() {
+
+    },
+
+    openDialog: function() {
+        this.currentDirectory = '',
+        this.getFileListingStore().removeAll();
+        reason.server.method("file_listing",
+            {base_dir:"", sub_dir:""}, this.fillStore);
+        this.win = Ext.widget("fileopenwindow");
+        this.win.query("#file_listing")[0].bindStore(this.getFileListingStore());
+        /* Set up our handlers */
+        this.control({
+            '#current_file': { specialkey: this.specialKeyPressed, },
+            '#file_listing': { celldblclick: this.doubleClicked, },
+            '#load': { click: this.loadFile, },
+            '#cancel': { click: this.cancelWindow, }
+        });
+        this.win.show();
+    },
+
+    specialKeyPressed: function(f, e) {
+        if (e.getKey() != e.ENTER) { return; }
+        reason.server.method("file_listing",
+            {base_dir:f.getValue(), sub_dir:""}, this.fillStore);
+    },  
+
+    doubleClicked: function(view, td, cellIndex, record) {
+        conf = {'base_dir': this.currentDirectory};
+        if (record.data.type == 'directory') {
+          conf['sub_dir'] = record.data.filename;
+          reason.server.method('file_listing', conf, this.fillStore);
+        } else {
+          conf['filename'] = record.data.filename;
+          reason.server.method('load', conf);
+          this.win.destroy();
+        }
+    },
+
+    loadFile: function(b, e) {
+        var conf = {filename: '', base_dir: this.currentDirectory};
+        var fl = this.win.query("#file_listing")[0];
+        var idx = fl.getSelectionModel().getSelection();
+        if (idx == 1) {
+            conf['filename'] = this.getFileListingStore().getAt(idx).data.filename;
+        }
+        reason.server.method('load', conf);
+    },
+
+    cancelWindow:  function(b, e) {
+        this.win.destroy();
+    },
+
+    fillStore: function(f, a) {
+        var con = reason.getController("FileOpen");
+        examine = a.result;
+        if(a.status == false){
+          Ext.Msg.alert("Error", "Something has gone wrong.");
+          con.window.destroy();
+        }
+        if(a.result['change'] == false) {
+          con.win.query("#current_file")[0].setValue(con.currentDirectory);
+          return;
+        }
+        con.getFileListingStore().removeAll();
+        var rec = [];
+        con.getFileListingStore().loadData(a.result['objs']);
+        con.currentDirectory = a.result['cur_dir'];
+        con.win.query("#current_file")[0].setValue(con.currentDirectory);
+    },
+});


diff -r 471a44f99c0452428e3800d0234e8dd12566e668 -r fd793137ae83b7ed58ad6e1181b5c991a5cdd3eb yt/gui/reason/html/app/controller/MenuActions.js
--- a/yt/gui/reason/html/app/controller/MenuActions.js
+++ b/yt/gui/reason/html/app/controller/MenuActions.js
@@ -73,7 +73,7 @@
     },
 
     openFile: function(b, e) {
-        alert("Not yet implemented.");
+        this.application.getController("FileOpen").openDialog();
     },
 
     downloadScript: function(b, e) {


diff -r 471a44f99c0452428e3800d0234e8dd12566e668 -r fd793137ae83b7ed58ad6e1181b5c991a5cdd3eb yt/gui/reason/html/app/store/FileListing.js
--- /dev/null
+++ b/yt/gui/reason/html/app/store/FileListing.js
@@ -0,0 +1,42 @@
+/**********************************************************************
+File Listing store for Reason
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define('Reason.store.FileListing', {
+    extend: 'Ext.data.ArrayStore',
+    id: 'filelisting',
+    fields: [
+        'filename', 
+        {name: 'size', type: 'float'},
+        'type'
+    ],
+    data: [],
+});
+


diff -r 471a44f99c0452428e3800d0234e8dd12566e668 -r fd793137ae83b7ed58ad6e1181b5c991a5cdd3eb yt/gui/reason/html/app/view/FileOpen.js
--- /dev/null
+++ b/yt/gui/reason/html/app/view/FileOpen.js
@@ -0,0 +1,107 @@
+/**********************************************************************
+File Open Dialog for Reason
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define('Reason.view.FileOpen', {
+    extend: 'Ext.window.Window',
+    alias: 'widget.fileopenwindow',
+
+    layout: {
+        type: 'vbox',
+        align: 'stretch',
+        pack: 'start',
+        defaultMargins: '5px 5px 5px 5px',
+    },
+    width: 540,
+    height: 480,
+    modal:true,
+    resizable:true,
+    draggable:true,
+    title:'Open File',
+
+    items: [
+        {
+          xtype: 'textfield',
+          itemId: 'current_file',
+          height: 35,
+        }, {
+          xtype:'gridpanel',
+          itemId: 'file_listing',
+          singleSelect:true,
+          emptyText: 'No files to display',
+          flex: 1.0,
+          columns: [
+          {
+              header: 'Type',
+              width: 24,
+              renderer: function(value) {
+                return Ext.String.format('<img src="reason/resources/images/' + 
+                                         'file_dialog_{0}.png"' + 
+                                         'width=16 height=16>', value);
+              },
+              dataIndex: 'type'
+          },{
+              header: 'Filename',
+              flex: 3.0,
+              dataIndex: 'filename'
+          },{
+              header: 'Size',
+              dataIndex: 'size',
+              tpl: '{size:fileSize}',
+              align: 'right',
+              cls: 'listview-filesize',
+              flex: 1.0,
+          }],
+        }, {
+          xtype: 'panel',
+          height: 40,
+          layout: {
+              type: 'hbox',
+              align: 'stretch',
+              pack: 'start',
+              defaultMargins: "5px 5px 5px 5px",
+          },
+          items: [
+            { flex: 1.0,
+              xtype: 'button',
+              text: 'Cancel', 
+              itemId: 'cancel',
+            }, { 
+              flex: 1.0,
+              xtype: 'button',
+              text: 'Load',
+              itemId: 'load',
+            },
+          ],
+        },
+    ],
+});
+
+


diff -r 471a44f99c0452428e3800d0234e8dd12566e668 -r fd793137ae83b7ed58ad6e1181b5c991a5cdd3eb yt/gui/reason/html/js/file_open.js
--- a/yt/gui/reason/html/js/file_open.js
+++ /dev/null
@@ -1,146 +0,0 @@
-/**********************************************************************
-A file opener
-
-Author: Matthew Turk <matthewturk at gmail.com>
-Affiliation: Columbia University
-Homepage: http://yt-project.org/
-License:
-  Copyright (C) 2012 Matthew Turk.  All Rights Reserved.
-
-  This file is part of yt.
-
-  yt is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 3 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-***********************************************************************/
-
-function open_file() {
-    var filestore = new Ext.data.ArrayStore({
-      fields: ['filename', 
-               {name:'size', type:'float'},
-               'type'
-      ]
-    });
-    var cur_dir;
-    function fillStore(f, a){
-        if(a.status == false){
-          Ext.Msg.alert("Error", "Something has gone wrong.");
-          return;
-        }
-        if(a.result['change'] == false) {
-          win.get("current_file").setValue(cur_dir);
-          return;
-        }
-        filestore.removeAll();
-        var rec = [];
-        filestore.loadData(a.result['objs']);
-        cur_dir = a.result['cur_dir'];
-        win.get("current_file").setValue(cur_dir);
-    }
-
-    var win = new Ext.Window({
-        layout:'vbox',
-        layoutConfig: {
-            align: 'stretch',
-            pack: 'start',
-            defaultMargins: "5px 5px 5px 5px",
-        },
-        width:540,
-        height:480,
-        modal:true,
-        resizable:true,
-        draggable:true,
-        title:'Open File',
-        items: [
-            { xtype: 'textfield',
-              id: 'current_file',
-              listeners: {
-                specialkey: function(f, e) {
-                  if (e.getKey() != e.ENTER) { return; }
-                  yt_rpc.ExtDirectREPL.file_listing(
-                        {base_dir:f.getValue(), sub_dir:''}, fillStore);
-                }
-              }
-            }, {
-              xtype:'listview',
-              id: 'file_listing',
-              store: filestore ,
-              singleSelect:true,
-              emptyText: 'No images to display',
-              flex: 1.0,
-              columns: [
-              {
-                  header: 'Type',
-                  width: 0.1,
-                  tpl: '<img src="images/file_dialog_{type}.png" width=16 height=16>',
-                  dataIndex: 'type'
-              },{
-                  header: 'Filename',
-                  width: .75,
-                  dataIndex: 'filename'
-              },{
-                  header: 'Size',
-                  dataIndex: 'size',
-                  tpl: '{size:fileSize}',
-                  align: 'right',
-                  cls: 'listview-filesize'
-              }],
-              listeners: {
-                dblclick: function(view, index, node, e) {
-                    var fileRecord = filestore.getAt(index).data;
-                    if (fileRecord.type == 'directory') {
-                      yt_rpc.ExtDirectREPL.file_listing(
-                            {base_dir:cur_dir, sub_dir:fileRecord.filename},
-                            fillStore);
-                    } else {
-                      yt_rpc.ExtDirectREPL.load(
-                            {base_dir:cur_dir, filename:fileRecord.filename},
-                            handle_result);
-                      win.destroy();
-                    }
-                },
-                selectionchange: function(view, index, node, e) {
-                },
-              },
-            }, {
-              xtype: 'panel',
-              height: 40,
-              layout: 'hbox',
-              layoutConfig: {
-                  align: 'stretch',
-                  pack: 'start',
-                  defaultMargins: "5px 5px 5px 5px",
-              },
-              items: [
-                { flex: 1.0, xtype: 'button', text: 'Cancel',
-                    handler: function(b, e) { win.destroy(); } },
-                { flex: 1.0, xtype: 'button', text: 'Load',
-                    handler: function(b, e) {
-                      filename = "";
-                      var fl = win.get("file_listing");
-                      if (fl.getSelectionCount() == 1) {
-                        filename = fl.getSelectedRecords()[0].data.filename;
-                      }
-                      yt_rpc.ExtDirectREPL.load(
-                            {base_dir:cur_dir, filename:filename},
-                            handle_result);
-                      win.destroy();
-                    }
-                },
-              ],
-            },
-        ],
-    });
-    yt_rpc.ExtDirectREPL.file_listing(
-          {base_dir:"", sub_dir:""}, fillStore);
-    win.show(this);
-}



https://bitbucket.org/yt_analysis/yt/changeset/3f114eed5c32/
changeset:   3f114eed5c32
branch:      yt
user:        MatthewTurk
date:        2012-06-15 16:14:44
summary:     Graceful shutdown.
affected #:  1 file

diff -r fd793137ae83b7ed58ad6e1181b5c991a5cdd3eb -r 3f114eed5c32b4557b823733e3a100c0dd76edcb yt/gui/reason/html/app/controller/ServerCommunication.js
--- a/yt/gui/reason/html/app/controller/ServerCommunication.js
+++ b/yt/gui/reason/html/app/controller/ServerCommunication.js
@@ -89,6 +89,10 @@
                             reason.fireEvent("payloadreceived", payload);
                     });
                 }
+                else if (!a.status) {
+                    reason.fireEvent("stopheartbeat");
+                    Ext.Msg.alert("Error", "Error talking to server.  Shutting down.");
+                }
                 return true;
             }
         );



https://bitbucket.org/yt_analysis/yt/changeset/1f6b809592d8/
changeset:   1f6b809592d8
branch:      yt
user:        MatthewTurk
date:        2012-06-15 21:19:58
summary:     Merging from yt tip
affected #:  17 files

diff -r 3f114eed5c32b4557b823733e3a100c0dd76edcb -r 1f6b809592d82ae9be010b236457849e22b8aa23 doc/install_script.sh
--- a/doc/install_script.sh
+++ b/doc/install_script.sh
@@ -353,7 +353,7 @@
 
 # Now we dump all our SHA512 files out.
 
-echo '2c1933ab31246b4f4eba049d3288156e0a72f1730604e3ed7357849967cdd329e4647cf236c9442ecfb06d0aff03e6fc892a7ba2a5c1cf5c011b7ab9c619acec  Cython-0.16.tar.gz ' > Cython-0.16.tar.gz.sha512
+echo '2c1933ab31246b4f4eba049d3288156e0a72f1730604e3ed7357849967cdd329e4647cf236c9442ecfb06d0aff03e6fc892a7ba2a5c1cf5c011b7ab9c619acec  Cython-0.16.tar.gz' > Cython-0.16.tar.gz.sha512
 echo 'b8a12bf05b3aafa71135e47da81440fd0f16a4bd91954bc5615ad3d3b7f9df7d5a7d5620dc61088dc6b04952c5c66ebda947a4cfa33ed1be614c8ca8c0f11dff  PhiloGL-1.4.2.zip' > PhiloGL-1.4.2.zip.sha512
 echo '44eea803870a66ff0bab08d13a8b3388b5578ebc1c807d1d9dca0a93e6371e91b15d02917a00b3b20dc67abb5a21dabaf9b6e9257a561f85eeff2147ac73b478  PyX-0.11.1.tar.gz' > PyX-0.11.1.tar.gz.sha512
 echo '1a754d560bfa433f0960ab3b5a62edb5f291be98ec48cf4e5941fa5b84139e200b87a52efbbd6fa4a76d6feeff12439eed3e7a84db4421940d1bbb576f7a684e  Python-2.7.2.tgz' > Python-2.7.2.tgz.sha512


diff -r 3f114eed5c32b4557b823733e3a100c0dd76edcb -r 1f6b809592d82ae9be010b236457849e22b8aa23 yt/analysis_modules/halo_profiler/api.py
--- a/yt/analysis_modules/halo_profiler/api.py
+++ b/yt/analysis_modules/halo_profiler/api.py
@@ -34,5 +34,4 @@
 from .multi_halo_profiler import \
     HaloProfiler, \
     FakeProfile, \
-    get_halo_sphere, \
     standard_fields


diff -r 3f114eed5c32b4557b823733e3a100c0dd76edcb -r 1f6b809592d82ae9be010b236457849e22b8aa23 yt/analysis_modules/halo_profiler/centering_methods.py
--- a/yt/analysis_modules/halo_profiler/centering_methods.py
+++ b/yt/analysis_modules/halo_profiler/centering_methods.py
@@ -43,14 +43,14 @@
 @add_function("Min_Dark_Matter_Density")
 def find_minimum_dm_density(data):
     ma, maxi, mx, my, mz, mg = data.quantities['MinLocation']('Dark_Matter_Density',
-                                                              lazy_reader=False,
+                                                              lazy_reader=True,
                                                               preload=False)
     return (mx, my, mz)
 
 @add_function("Max_Dark_Matter_Density")
 def find_maximum_dm_density(data):
     ma, maxi, mx, my, mz, mg = data.quantities['MaxLocation']('Dark_Matter_Density',
-                                                              lazy_reader=False,
+                                                              lazy_reader=True,
                                                               preload=False)
     return (mx, my, mz)
 
@@ -58,7 +58,7 @@
 def find_CoM_dm_density(data):
    dc_x, dc_y, dc_z = data.quantities['CenterOfMass'](use_cells=False, 
                                                       use_particles=True,
-                                                      lazy_reader=False,
+                                                      lazy_reader=True,
                                                       preload=False)
    return (dc_x, dc_y, dc_z)
 
@@ -67,14 +67,14 @@
 @add_function("Min_Gas_Density")
 def find_minimum_gas_density(data):
     ma, maxi, mx, my, mz, mg = data.quantities['MinLocation']('Density',
-                                                              lazy_reader=False,
+                                                              lazy_reader=True,
                                                               preload=False)
     return (mx, my, mz)
 
 @add_function("Max_Gas_Density")
 def find_maximum_gas_density(data):
     ma, maxi, mx, my, mz, mg = data.quantities['MaxLocation']('Density',
-                                                              lazy_reader=False,
+                                                              lazy_reader=True,
                                                               preload=False)
     return (mx, my, mz)
 
@@ -82,7 +82,7 @@
 def find_CoM_gas_density(data):
    dc_x, dc_y, dc_z = data.quantities['CenterOfMass'](use_cells=True, 
                                                       use_particles=False,
-                                                      lazy_reader=False,
+                                                      lazy_reader=True,
                                                       preload=False)
    return (dc_x, dc_y, dc_z)
 
@@ -91,14 +91,14 @@
 @add_function("Min_Total_Density")
 def find_minimum_total_density(data):
     ma, maxi, mx, my, mz, mg = data.quantities['MinLocation']('Matter_Density',
-                                                              lazy_reader=False,
+                                                              lazy_reader=True,
                                                               preload=False)
     return (mx, my, mz)
 
 @add_function("Max_Total_Density")
 def find_maximum_total_density(data):
     ma, maxi, mx, my, mz, mg = data.quantities['MaxLocation']('Matter_Density',
-                                                              lazy_reader=False,
+                                                              lazy_reader=True,
                                                               preload=False)
     return (mx, my, mz)
 
@@ -106,7 +106,7 @@
 def find_CoM_total_density(data):
    dc_x, dc_y, dc_z = data.quantities['CenterOfMass'](use_cells=True, 
                                                       use_particles=True,
-                                                      lazy_reader=False,
+                                                      lazy_reader=True,
                                                       preload=False)
    return (dc_x, dc_y, dc_z)
 
@@ -115,14 +115,14 @@
 @add_function("Min_Temperature")
 def find_minimum_temperature(data):
     ma, mini, mx, my, mz, mg = data.quantities['MinLocation']('Temperature',
-                                                              lazy_reader=False,
+                                                              lazy_reader=True,
                                                               preload=False)
     return (mx, my, mz)
 
 @add_function("Max_Temperature")
 def find_maximum_temperature(data):
     ma, maxi, mx, my, mz, mg = data.quantities['MaxLocation']('Temperature',
-                                                              lazy_reader=False,
+                                                              lazy_reader=True,
                                                               preload=False)
     return (mx, my, mz)
 


diff -r 3f114eed5c32b4557b823733e3a100c0dd76edcb -r 1f6b809592d82ae9be010b236457849e22b8aa23 yt/analysis_modules/halo_profiler/multi_halo_profiler.py
--- a/yt/analysis_modules/halo_profiler/multi_halo_profiler.py
+++ b/yt/analysis_modules/halo_profiler/multi_halo_profiler.py
@@ -42,6 +42,8 @@
     centering_registry
 from yt.data_objects.field_info_container import \
     add_field
+from yt.data_objects.static_output import \
+    StaticOutput
 
 from yt.utilities.parallel_tools.parallel_analysis_interface import \
     ParallelAnalysisInterface, \
@@ -64,7 +66,7 @@
                                          dm_only=False, resize=True, 
                                          fancy_padding=True, rearrange=True),
                  halo_radius=None, radius_units='1', n_profile_bins=50,
-                 recenter = None,
+                 recenter=None,
                  profile_output_dir='radial_profiles', projection_output_dir='projections',
                  projection_width=8.0, projection_width_units='mpc', project_at_level='max',
                  velocity_center=['bulk', 'halo'], filter_quantities=['id', 'center', 'r_max'], 
@@ -111,8 +113,32 @@
             Args given with call to halo finder function.  Default: None.
         halo_finder_kwargs : dict
             kwargs given with call to halo finder function. Default: None.
-        recenter : {string, function
-            The name of a function that recenters the halo for analysis.
+        recenter : {string, function}
+            The exact location of the sphere center can significantly affect 
+            radial profiles.  The halo center loaded by the HaloProfiler will 
+            typically be the dark matter center of mass calculated by a halo 
+            finder.  However, this may not be the best location for centering 
+            profiles of baryon quantities.  For example, one may want to center 
+            on the maximum density.
+            If recenter is given as a string, one of the existing recentering 
+            functions will be used:
+                Min_Dark_Matter_Density : location of minimum dark matter density
+                Max_Dark_Matter_Density : location of maximum dark matter density
+                CoM_Dark_Matter_Density : dark matter center of mass
+                Min_Gas_Density : location of minimum gas density
+                Max_Gas_Density : location of maximum gas density
+                CoM_Gas_Density : gas center of mass
+                Min_Total_Density : location of minimum total density
+                Max_Total_Density : location of maximum total density
+                CoM_Total_Density : total center of mass
+                Min_Temperature : location of minimum temperature
+                Max_Temperature : location of maximum temperature
+            Alternately, a function can be supplied for custom recentering.
+            The function should take only one argument, a sphere object.
+                Example function:
+                    def my_center_of_mass(data):
+                       my_x, my_y, my_z = data.quantities['CenterOfMass']()
+                       return (my_x, my_y, my_z)
             Default: None.
         halo_radius : float
             If no halo radii are provided in the halo list file, this
@@ -148,8 +174,7 @@
                 * ["bulk", "sphere"]: the bulk velocity of the sphere
                   centered on the halo center.
     	        * ["max", field]: the velocity of the cell that is the
-    	          location of the maximum of the field 
-                  specified (used only when halos set to single).
+    	          location of the maximum of the field specified.
         filter_quantities : array_like
             Quantities from the original halo list file to be written out in the 
             filtered list file.  Default: ['id','center'].
@@ -161,8 +186,8 @@
         
         Examples
         --------
-        >>> import yt.analysis_modules.halo_profiler.api as HP
-        >>> hp = HP.halo_profiler("DD0242/DD0242")
+        >>> from yt.analysis_modules.halo_profiler.api import *
+        >>> hp = HaloProfiler("RedshiftOutput0005/RD0005")
         
         """
         ParallelAnalysisInterface.__init__(self)
@@ -226,13 +251,9 @@
         # Option to recenter sphere someplace else.
         self.recenter = recenter
 
-        # Look for any field that might need to have the bulk velocity set.
+        # Flag for whether calculating halo bulk velocity is necessary.
         self._need_bulk_velocity = False
-        for field in [hp['field'] for hp in self.profile_fields]:
-            if 'Velocity' in field or 'Mach' in field:
-                self._need_bulk_velocity = True
-                break
-
+        
         # Check validity for VelocityCenter parameter which toggles how the 
         # velocity is zeroed out for radial velocity profiles.
         self.velocity_center = velocity_center[:]
@@ -250,15 +271,16 @@
                 mylog.error("Second value of VelocityCenter must be either 'halo' or 'sphere' if first value is 'bulk'.")
                 return None
         elif self.velocity_center[0] == 'max':
-            if self.halos is 'multiple':
-                mylog.error("Getting velocity center from a max field value only works with halos='single'.")
-                return None
+            mylog.info('Using position of max %s for velocity center.' % self.velocity_center[1])
         else:
             mylog.error("First value of parameter, VelocityCenter, must be either 'bulk' or 'max'.")
             return None
 
         # Create dataset object.
-        self.pf = load(self.dataset)
+        if isinstance(self.dataset, StaticOutput):
+            self.pf = self.dataset
+        else:
+            self.pf = load(self.dataset)
         self.pf.h
 
         # Figure out what max radius to use for profiling.
@@ -284,7 +306,7 @@
                 mylog.error("No halos loaded, there will be nothing to do.")
                 return None
         else:
-            mylog.error("I don't know whether to get halos from hop or from density maximum.  This should not have happened.")
+            mylog.error("Keyword, halos, must be either 'single' or 'multiple'.")
             return None
 
     def add_halo_filter(self, function, *args, **kwargs):
@@ -351,6 +373,10 @@
             
         """
 
+        # Check for any field that might need to have the bulk velocity set.
+        if 'Velocity' in field or 'Mach' in field:
+            self._need_bulk_velocity = True
+
         self.profile_fields.append({'field':field, 'weight_field':weight_field, 
                                     'accumulation':accumulation})
 
@@ -379,11 +405,15 @@
 
         """
 
+        # Check for any field that might need to have the bulk velocity set.
+        if 'Velocity' in field or 'Mach' in field:
+            self._need_bulk_velocity = True
+
         self.projection_fields.append({'field':field, 'weight_field':weight_field, 
                                        'cmap': cmap})
 
     @parallel_blocking_call
-    def make_profiles(self, filename=None, prefilters=None, **kwargs):
+    def make_profiles(self, filename=None, prefilters=None, njobs=-1):
         r"""Make radial profiles for all halos in the list.
         
         After all the calls to `add_profile`, this will trigger the actual
@@ -394,7 +424,7 @@
         filename : string
             If set, a file will be written with all of the filtered halos
             and the quantities returned by the filter functions.
-            Default=None.
+            Default: None.
         prefilters : array_like
             A single dataset can contain thousands or tens of thousands of
             halos. Significant time can be saved by not profiling halos
@@ -402,6 +432,11 @@
             Simple filters based on quantities provided in the initial
             halo list can be used to filter out unwanted halos using this
             parameter.
+            Default: None.
+        njobs : int
+            The number of jobs over which to split the profiling.  Set
+            to -1 so that each halo is done by a single processor.
+            Default: -1.
         
         Examples
         --------
@@ -454,7 +489,7 @@
 
         # Profile all halos.
         updated_halos = []
-        for halo in parallel_objects(self.all_halos, -1):
+        for halo in parallel_objects(self.all_halos, njobs=njobs):
             # Apply prefilters to avoid profiling unwanted halos.
             filter_result = True
             haloQuantities = {}
@@ -468,7 +503,8 @@
 
                 profile_filename = "%s/Halo_%04d_profile.dat" % (my_output_dir, halo['id'])
 
-                profiledHalo = self._get_halo_profile(halo, profile_filename, virial_filter=virial_filter)
+                profiledHalo = self._get_halo_profile(halo, profile_filename,
+                                                      virial_filter=virial_filter)
 
                 if profiledHalo is None:
                     continue
@@ -487,26 +523,26 @@
                 for quantity in self.filter_quantities:
                     if halo.has_key(quantity): haloQuantities[quantity] = halo[quantity]
 
-                self.filtered_halos.append(haloQuantities)
+                only_on_root(self.filtered_halos.append, haloQuantities)
 
             # If we've gotten this far down, this halo is good and we want
             # to keep it. But we need to communicate the recentering changes
             # to all processors (the root one in particular) without having
             # one task clobber the other.
-            updated_halos.append(halo)
-        
+            only_on_root(updated_halos.append, halo)
+
         # And here is where we bring it all together.
         updated_halos = self.comm.par_combine_object(updated_halos,
                             datatype="list", op="cat")
-        updated_halos.sort(key = lambda a:a['id'])
+        updated_halos.sort(key=lambda a:a['id'])
         self.all_halos = updated_halos
 
         self.filtered_halos = self.comm.par_combine_object(self.filtered_halos,
                             datatype="list", op="cat")
-        self.filtered_halos.sort(key = lambda a:a['id'])
+        self.filtered_halos.sort(key=lambda a:a['id'])
 
         if filename is not None:
-            self._write_filtered_halo_list(filename, **kwargs)
+            self._write_filtered_halo_list(filename)
 
     def _get_halo_profile(self, halo, filename, virial_filter=True,
             force_write=False):
@@ -529,31 +565,13 @@
                 return None
 
             # get a sphere object to profile
-            sphere = get_halo_sphere(halo, self.pf, recenter=self.recenter)
+            sphere = self._get_halo_sphere(halo)
             if sphere is None: return None
 
-            if self._need_bulk_velocity:
-                # Set bulk velocity to zero out radial velocity profiles.
-                if self.velocity_center[0] == 'bulk':
-                    if self.velocity_center[1] == 'halo':
-                        sphere.set_field_parameter('bulk_velocity', halo['velocity'])
-                    elif self.velocity_center[1] == 'sphere':
-                        sphere.set_field_parameter('bulk_velocity', 
-                                                   sphere.quantities['BulkVelocity'](lazy_reader=False, 
-                                                                                     preload=False))
-                    else:
-                        mylog.error("Invalid parameter: VelocityCenter.")
-                elif self.velocity_center[0] == 'max':
-                    max_grid, max_cell, max_value, max_location = \
-                        self.pf.h.find_max_cell_location(self.velocity_center[1])
-                    sphere.set_field_parameter('bulk_velocity', [max_grid['x-velocity'][max_cell],
-                                                                 max_grid['y-velocity'][max_cell],
-                                                                 max_grid['z-velocity'][max_cell]])
-
             try:
                 profile = BinnedProfile1D(sphere, self.n_profile_bins, "RadiusMpc",
                                                 r_min, halo['r_max'],
-                                                log_space=True, lazy_reader=False,
+                                                log_space=True, lazy_reader=True,
                                                 end_collect=True)
             except EmptyProfileData:
                 mylog.error("Caught EmptyProfileData exception, returning None for this halo.")
@@ -586,9 +604,75 @@
 
         return profile
 
+    def _get_halo_sphere(self, halo):
+        """
+        Returns a sphere object for a given halo, performs the recentering,
+        and calculates bulk velocities.
+        """
+
+        sphere = self.pf.h.sphere(halo['center'], halo['r_max']/self.pf.units['mpc'])
+        if len(sphere._grids) == 0: return None
+        new_sphere = False
+
+        if self.recenter:
+            old = halo['center']
+            if self.recenter in centering_registry:
+                new_x, new_y, new_z = \
+                    centering_registry[self.recenter](sphere)
+            else:
+                # user supplied function
+                new_x, new_y, new_z = self.recenter(sphere)
+            if new_x < self.pf.domain_left_edge[0] or \
+                    new_y < self.pf.domain_left_edge[1] or \
+                    new_z < self.pf.domain_left_edge[2]:
+                mylog.info("Recentering rejected, skipping halo %d" % \
+                    halo['id'])
+                return None
+            halo['center'] = [new_x, new_y, new_z]
+            d = self.pf['kpc'] * periodic_dist(old, halo['center'],
+                self.pf.domain_right_edge - self.pf.domain_left_edge)
+            mylog.info("Recentered halo %d %1.3e kpc away." % (halo['id'], d))
+            # Expand the halo to account for recentering. 
+            halo['r_max'] += d / 1000. # d is in kpc -> want mpc
+            new_sphere = True
+
+        if new_sphere:
+            # Temporary solution to memory leak.
+            for g in self.pf.h.grids:
+                g.clear_data()
+            sphere.clear_data()
+            del sphere
+            sphere = self.pf.h.sphere(halo['center'], halo['r_max']/self.pf.units['mpc'])
+
+        if self._need_bulk_velocity:
+            # Set bulk velocity to zero out radial velocity profiles.
+            if self.velocity_center[0] == 'bulk':
+                if self.velocity_center[1] == 'halo':
+                    sphere.set_field_parameter('bulk_velocity', halo['velocity'])
+                elif self.velocity_center[1] == 'sphere':
+                    mylog.info('Calculating sphere bulk velocity.')
+                    sphere.set_field_parameter('bulk_velocity', 
+                                               sphere.quantities['BulkVelocity'](lazy_reader=True, 
+                                                                                 preload=False))
+                else:
+                    mylog.error("Invalid parameter: velocity_center.")
+                    return None
+            elif self.velocity_center[0] == 'max':
+                mylog.info('Setting bulk velocity with value at max %s.' % self.velocity_center[1])
+                max_val, maxi, mx, my, mz, mg = sphere.quantities['MaxLocation'](self.velocity_center[1],
+                                                                                 lazy_reader=True)
+                max_grid = self.pf.h.grids[mg]
+                max_cell = na.unravel_index(maxi, max_grid.ActiveDimensions)
+                sphere.set_field_parameter('bulk_velocity', [max_grid['x-velocity'][max_cell],
+                                                             max_grid['y-velocity'][max_cell],
+                                                             max_grid['z-velocity'][max_cell]])
+            mylog.info('Bulk velocity set.')
+
+        return sphere
+
     @parallel_blocking_call
     def make_projections(self, axes=[0, 1, 2], halo_list='filtered',
-            save_images=False, save_cube=True):
+                         save_images=False, save_cube=True, njobs=-1):
         r"""Make projections of all halos using specified fields.
         
         After adding fields using `add_projection`, this starts the actual
@@ -608,6 +692,10 @@
         save_cube : bool
             Whether or not to save the HDF5 files of the halo projections.
             Default=True.
+        njobs : int
+            The number of jobs over which to split the projections.  Set
+            to -1 so that each halo is done by a single processor.
+            Default: -1.
         
         Examples
         --------
@@ -656,7 +744,7 @@
                          self.pf.parameters['DomainRightEdge'][w])
                   for w in range(self.pf.parameters['TopGridRank'])]
 
-        for halo in parallel_objects(halo_projection_list, -1):
+        for halo in parallel_objects(halo_projection_list, njobs=njobs):
             if halo is None:
                 continue
             # Check if region will overlap domain edge.
@@ -745,7 +833,7 @@
 
     @parallel_blocking_call
     def analyze_halo_spheres(self, analysis_function, halo_list='filtered',
-                             analysis_output_dir=None):
+                             analysis_output_dir=None, njobs=-1):
         r"""Perform custom analysis on all halos.
         
         This will loop through all halo on the HaloProfiler's list, 
@@ -768,6 +856,10 @@
         analysis_output_dir : string, optional
             If specified, this directory will be created within the dataset to 
             contain any output from the analysis function.  Default: None.
+        njobs : int
+            The number of jobs over which to split the analysis.  Set
+            to -1 so that each halo is done by a single processor.
+            Default: -1.
 
         Examples
         --------
@@ -803,11 +895,11 @@
                 my_output_dir = "%s/%s" % (self.pf.fullpath, analysis_output_dir)
             self.__check_directory(my_output_dir)
 
-        for halo in parallel_objects(halo_analysis_list, -1):
+        for halo in parallel_objects(halo_analysis_list, njobs=njobs):
             if halo is None: continue
 
             # Get a sphere object to analze.
-            sphere = get_halo_sphere(halo, self.pf, recenter=self.recenter)
+            sphere = self._get_halo_sphere(halo)
             if sphere is None: continue
 
             # Call the given analysis function.
@@ -924,6 +1016,9 @@
         lines = f.readlines()
         f.close()
 
+        if not lines:
+            return None
+
         # Get fields from header.
         header = lines.pop(0)
         header = header.strip()
@@ -1042,94 +1137,6 @@
         else:
             os.mkdir(my_output_dir)
 
-def get_halo_sphere(halo, pf, recenter=None):
-    r"""Returns a sphere object for a given halo.
-        
-    With a dictionary containing halo properties, such as center 
-    and r_max, this creates a sphere object and optionally 
-    recenters and recreates the sphere using a recentering function.
-    This is to be used primarily to make spheres for a set of halos 
-    loaded by the HaloProfiler.
-    
-    Parameters
-    ----------
-    halo : dict, required
-        The dictionary containing halo properties used to make the sphere.
-        Required entries:
-            center : list with center coordinates.
-            r_max : sphere radius in Mpc.
-    pf : parameter file object, required
-        The parameter file from which the sphere will be made.
-    recenter : {None, string or function}
-        The exact location of the sphere center can significantly affect 
-        radial profiles.  The halo center loaded by the HaloProfiler will 
-        typically be the dark matter center of mass calculated by a halo 
-        finder.  However, this may not be the best location for centering 
-        profiles of baryon quantities.  For example, one may want to center 
-        on the maximum density.
-        If recenter is given as a string, one of the existing recentering 
-        functions will be used:
-            Min_Dark_Matter_Density : location of minimum dark matter density
-            Max_Dark_Matter_Density : location of maximum dark matter density
-            CoM_Dark_Matter_Density : dark matter center of mass
-            Min_Gas_Density : location of minimum gas density
-            Max_Gas_Density : location of maximum gas density
-            CoM_Gas_Density : gas center of mass
-            Min_Total_Density : location of minimum total density
-            Max_Total_Density : location of maximum total density
-            CoM_Total_Density : total center of mass
-            Min_Temperature : location of minimum temperature
-            Max_Temperature : location of maximum temperature
-        Alternately, a function can be supplied for custom recentering.
-        The function should take only one argument, a sphere object.
-            Example function:
-                def my_center_of_mass(data):
-                   my_x, my_y, my_z = data.quantities['CenterOfMass']()
-                   return (my_x, my_y, my_z)
-
-        Examples: this should primarily be used with the halo list of the HaloProfiler.
-        This is an example with an abstract halo asssuming a pre-defined pf.
-        >>> halo = {'center': [0.5, 0.5, 0.5], 'r_max': 1.0}
-        >>> my_sphere = get_halo_sphere(halo, pf, recenter='Max_Gas_Density')
-        >>> # Assuming the above example function has been defined.
-        >>> my_sphere = get_halo_sphere(halo, pf, recenter=my_center_of_mass)
-    """
-        
-    sphere = pf.h.sphere(halo['center'], halo['r_max']/pf.units['mpc'])
-    if len(sphere._grids) == 0: return None
-    new_sphere = False
-
-    if recenter:
-        old = halo['center']
-        if recenter in centering_registry:
-            new_x, new_y, new_z = \
-                centering_registry[recenter](sphere)
-        else:
-            # user supplied function
-            new_x, new_y, new_z = recenter(sphere)
-        if new_x < pf.domain_left_edge[0] or \
-                new_y < pf.domain_left_edge[1] or \
-                new_z < pf.domain_left_edge[2]:
-            mylog.info("Recentering rejected, skipping halo %d" % \
-                halo['id'])
-            return None
-        halo['center'] = [new_x, new_y, new_z]
-        d = pf['kpc'] * periodic_dist(old, halo['center'],
-            pf.domain_right_edge - pf.domain_left_edge)
-        mylog.info("Recentered halo %d %1.3e kpc away." % (halo['id'], d))
-        # Expand the halo to account for recentering. 
-        halo['r_max'] += d / 1000 # d is in kpc -> want mpc
-        new_sphere = True
-
-    if new_sphere:
-        # Temporary solution to memory leak.
-        for g in pf.h.grids:
-            g.clear_data()
-        sphere.clear_data()
-        del sphere
-        sphere = pf.h.sphere(halo['center'], halo['r_max']/pf.units['mpc'])
-    return sphere
-
 def _shift_projections(pf, projections, oldCenter, newCenter, axis):
     """
     Shift projection data around.


diff -r 3f114eed5c32b4557b823733e3a100c0dd76edcb -r 1f6b809592d82ae9be010b236457849e22b8aa23 yt/convenience.py
--- a/yt/convenience.py
+++ b/yt/convenience.py
@@ -33,6 +33,7 @@
 from yt.config import ytcfg
 from yt.utilities.parameter_file_storage import \
     output_type_registry, \
+    simulation_time_series_registry, \
     EnzoRunDatabase
 
 def load(*args ,**kwargs):
@@ -111,3 +112,14 @@
     f.close()
     return proj
 
+def simulation(parameter_filename, simulation_type):
+    """
+    Loads a simulation time series object of the specified
+    simulation type.
+    """
+
+    if simulation_type not in simulation_time_series_registry:
+        raise YTSimulationNotIdentified(simulation_type)
+
+    return simulation_time_series_registry[simulation_type](parameter_filename)
+


diff -r 3f114eed5c32b4557b823733e3a100c0dd76edcb -r 1f6b809592d82ae9be010b236457849e22b8aa23 yt/data_objects/data_containers.py
--- a/yt/data_objects/data_containers.py
+++ b/yt/data_objects/data_containers.py
@@ -495,7 +495,7 @@
         self._sorted = {}
 
     def get_data(self, fields=None, in_grids=False):
-        if self._grids == None:
+        if self._grids is None:
             self._get_list_of_grids()
         points = []
         if not fields:
@@ -2543,7 +2543,18 @@
     def cut_region(self, field_cuts):
         """
         Return an InLineExtractedRegion, where the grid cells are cut on the
-        fly with a set of field_cuts.
+        fly with a set of field_cuts.  It is very useful for applying 
+        conditions to the fields in your data object.
+        
+        Examples
+        --------
+        To find the total mass of gas above 10^6 K in your volume:
+
+        >>> pf = load("RedshiftOutput0005")
+        >>> ad = pf.h.all_data()
+        >>> cr = ad.cut_region(["grid['Temperature'] > 1e6"])
+        >>> print cr.quantities["TotalQuantity"]("CellMassMsun")
+
         """
         return InLineExtractedRegionBase(self, field_cuts)
 
@@ -3292,6 +3303,40 @@
         pointI = na.where(k == True)
         return pointI
 
+class AMRMaxLevelCollection(AMR3DData):
+    _type_name = "grid_collection_max_level"
+    _con_args = ("center", "max_level")
+    def __init__(self, center, max_level, fields = None,
+                 pf = None, **kwargs):
+        """
+        By selecting an arbitrary *max_level*, we can act on those grids.
+        Child cells are masked when the level of the grid is below the max
+        level.
+        """
+        AMR3DData.__init__(self, center, fields, pf, **kwargs)
+        self.max_level = max_level
+        self._refresh_data()
+
+    def _get_list_of_grids(self):
+        if self._grids is not None: return
+        gi = (self.pf.h.grid_levels <= self.max_level)[:,0]
+        self._grids = self.pf.h.grids[gi]
+
+    def _is_fully_enclosed(self, grid):
+        return True
+
+    @cache_mask
+    def _get_cut_mask(self, grid):
+        return na.ones(grid.ActiveDimensions, dtype='bool')
+
+    def _get_point_indices(self, grid, use_child_mask=True):
+        k = na.ones(grid.ActiveDimensions, dtype='bool')
+        if use_child_mask and grid.Level < self.max_level:
+            k[grid.child_indices] = False
+        pointI = na.where(k == True)
+        return pointI
+
+
 class AMRSphereBase(AMR3DData):
     """
     A sphere of points
@@ -3369,8 +3414,6 @@
             The left edge of the region to be extracted
         dims : array_like
             Number of cells along each axis of resulting covering_grid
-        right_edge : array_like, optional
-            The right edge of the region to be extracted
         fields : array_like, optional
             A list of fields that you'd like pre-generated for your object
 
@@ -3529,16 +3572,13 @@
         left_edge : array_like
             The left edge of the region to be extracted
         dims : array_like
-            Number of cells along each axis of resulting covering_grid
-        right_edge : array_like, optional
-            The right edge of the region to be extracted
+            Number of cells along each axis of resulting covering_grid.
         fields : array_like, optional
             A list of fields that you'd like pre-generated for your object
 
         Example
         -------
         cube = pf.h.smoothed_covering_grid(2, left_edge=[0.0, 0.0, 0.0], \
-                                  right_edge=[1.0, 1.0, 1.0],
                                   dims=[128, 128, 128])
         """
         self._base_dx = (
@@ -3577,10 +3617,16 @@
         for gi, grid in enumerate(self._grids):
             if self._use_pbar: pbar.update(gi)
             if grid.Level > last_level and grid.Level <= self.level:
+                mylog.debug("Updating level state to %s", last_level + 1)
                 self._update_level_state(last_level + 1)
                 self._refine(1, fields_to_get)
                 last_level = grid.Level
             self._get_data_from_grid(grid, fields_to_get)
+        while last_level < self.level:
+            mylog.debug("Grid-free refinement %s to %s", last_level, last_level + 1)
+            self._update_level_state(last_level + 1)
+            self._refine(1, fields_to_get)
+            last_level += 1
         if self.level > 0:
             for field in fields_to_get:
                 self[field] = self[field][1:-1,1:-1,1:-1]


diff -r 3f114eed5c32b4557b823733e3a100c0dd76edcb -r 1f6b809592d82ae9be010b236457849e22b8aa23 yt/data_objects/hierarchy.py
--- a/yt/data_objects/hierarchy.py
+++ b/yt/data_objects/hierarchy.py
@@ -381,18 +381,18 @@
         """
         Prints out (stdout) relevant information about the simulation
         """
-        header = "%3s\t%6s\t%11s" % ("level","# grids", "# cells")
+        header = "%3s\t%6s\t%14s" % ("level","# grids", "# cells")
         print header
         print "%s" % (len(header.expandtabs())*"-")
         for level in xrange(MAXLEVEL):
             if (self.level_stats['numgrids'][level]) == 0:
                 break
-            print "% 3i\t% 6i\t% 11i" % \
+            print "% 3i\t% 6i\t% 14i" % \
                   (level, self.level_stats['numgrids'][level],
                    self.level_stats['numcells'][level])
             dx = self.select_grids(level)[0].dds[0]
         print "-" * 28
-        print "   \t% 6i\t% 11i" % (self.level_stats['numgrids'].sum(), self.level_stats['numcells'].sum())
+        print "   \t% 6i\t% 14i" % (self.level_stats['numgrids'].sum(), self.level_stats['numcells'].sum())
         print "\n"
         try:
             print "z = %0.8f" % (self["CosmologyCurrentRedshift"])


diff -r 3f114eed5c32b4557b823733e3a100c0dd76edcb -r 1f6b809592d82ae9be010b236457849e22b8aa23 yt/data_objects/time_series.py
--- a/yt/data_objects/time_series.py
+++ b/yt/data_objects/time_series.py
@@ -33,7 +33,9 @@
 from .derived_quantities import quantity_info
 from yt.utilities.exceptions import YTException
 from yt.utilities.parallel_tools.parallel_analysis_interface \
-    import parallel_objects
+    import parallel_objects, parallel_root_only
+from yt.utilities.parameter_file_storage import \
+    simulation_time_series_registry
 
 class AnalysisTaskProxy(object):
     def __init__(self, time_series):
@@ -189,3 +191,67 @@
         # hierarchy
         cls = getattr(pf.h, self.data_object_name)
         return cls(*self._args, **self._kwargs)
+
+
+class SimulationTimeSeries(TimeSeriesData):
+    class __metaclass__(type):
+        def __init__(cls, name, b, d):
+            type.__init__(cls, name, b, d)
+            code_name = name[:name.find('Simulation')]
+            if code_name:
+                simulation_time_series_registry[code_name] = cls
+                mylog.debug("Registering simulation: %s as %s", code_name, cls)
+
+    def __init__(self, parameter_filename):
+        """
+        Base class for generating simulation time series types.
+        Principally consists of a *parameter_filename*.
+        """
+
+        if not os.path.exists(parameter_filename):
+            raise IOError(parameter_filename)
+        self.parameter_filename = parameter_filename
+        self.basename = os.path.basename(parameter_filename)
+        self.directory = os.path.dirname(parameter_filename)
+        self.parameters = {}
+
+        # Set some parameter defaults.
+        self._set_parameter_defaults()
+        # Read the simulation parameter file.
+        self._parse_parameter_file()
+        # Set up time units dictionary.
+        self._set_time_units()
+
+        # Figure out the starting and stopping times and redshift.
+        self._calculate_simulation_bounds()
+        self.print_key_parameters()
+        
+        # Get all possible datasets.
+        self._get_all_outputs()
+
+    def __repr__(self):
+        return self.parameter_filename
+
+    @parallel_root_only
+    def print_key_parameters(self):
+        """
+        Print out some key parameters for the simulation.
+        """
+        for a in ["domain_dimensions", "domain_left_edge",
+                  "domain_right_edge", "initial_time", "final_time",
+                  "stop_cycle", "cosmological_simulation"]:
+            if not hasattr(self, a):
+                mylog.error("Missing %s in parameter file definition!", a)
+                continue
+            v = getattr(self, a)
+            mylog.info("Parameters: %-25s = %s", a, v)
+        if hasattr(self, "cosmological_simulation") and \
+           getattr(self, "cosmological_simulation"):
+            for a in ["omega_lambda", "omega_matter",
+                      "hubble_constant", "initial_redshift",
+                      "final_redshift"]:
+                if not hasattr(self, a):
+                    mylog.error("Missing %s in parameter file definition!", a)
+                    continue
+                v = getattr(self, a)
+                mylog.info("Parameters: %-25s = %s", a, v)


diff -r 3f114eed5c32b4557b823733e3a100c0dd76edcb -r 1f6b809592d82ae9be010b236457849e22b8aa23 yt/frontends/enzo/api.py
--- a/yt/frontends/enzo/api.py
+++ b/yt/frontends/enzo/api.py
@@ -38,6 +38,9 @@
       EnzoStaticOutput, \
       EnzoStaticOutputInMemory
 
+from .simulation_handling import \
+    EnzoSimulation
+
 from .fields import \
       EnzoFieldInfo, \
       Enzo2DFieldInfo, \


diff -r 3f114eed5c32b4557b823733e3a100c0dd76edcb -r 1f6b809592d82ae9be010b236457849e22b8aa23 yt/frontends/enzo/io.py
--- a/yt/frontends/enzo/io.py
+++ b/yt/frontends/enzo/io.py
@@ -201,6 +201,8 @@
     _data_style = "enzo_packed_3d_gz"
 
     def modify(self, field):
+        if len(field.shape) < 3:
+            return field
         tr = field[3:-3,3:-3,3:-3].swapaxes(0,2)
         return tr.copy() # To ensure contiguous
 


diff -r 3f114eed5c32b4557b823733e3a100c0dd76edcb -r 1f6b809592d82ae9be010b236457849e22b8aa23 yt/frontends/enzo/simulation_handling.py
--- /dev/null
+++ b/yt/frontends/enzo/simulation_handling.py
@@ -0,0 +1,633 @@
+"""
+EnzoSimulation class and member functions.
+
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: Michigan State University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2008-2012 Britton Smith.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+"""
+
+from yt.funcs import *
+
+import numpy as na
+import glob
+import os
+
+from yt.data_objects.time_series import \
+    SimulationTimeSeries, TimeSeriesData
+from yt.utilities.cosmology import \
+    Cosmology, \
+    EnzoCosmology
+from yt.utilities.exceptions import \
+    AmbiguousOutputs, \
+    MissingParameter, \
+    NoStoppingCondition
+
+from yt.convenience import \
+    load
+
+class EnzoSimulation(SimulationTimeSeries):
+    r"""Class for creating TimeSeriesData object from an Enzo
+    simulation parameter file.
+    """
+    def __init__(self, parameter_filename):
+        r"""Initialize an Enzo Simulation object.
+
+        Upon creation, the parameter file is parsed and the time and redshift
+        are calculated and stored in all_outputs.  A time units dictionary is
+        instantiated to allow for time outputs to be requested with physical
+        time units.  The get_time_series can be used to generate a
+        TimeSeriesData object.
+
+        parameter_filename : str
+            The simulation parameter file.
+        
+        Examples
+        --------
+        >>> from yt.mods import *
+        >>> es = ES.EnzoSimulation("my_simulation.par")
+        >>> print es.all_outputs
+
+        """
+        SimulationTimeSeries.__init__(self, parameter_filename)
+        
+    def get_time_series(self, time_data=True, redshift_data=True,
+                        initial_time=None, final_time=None, time_units='1',
+                        initial_redshift=None, final_redshift=None,
+                        initial_cycle=None, final_cycle=None,
+                        times=None, redshifts=None, tolerance=None,
+                        find_outputs=False, parallel=True):
+
+        """
+        Instantiate a TimeSeriesData object for a set of outputs.
+
+        If no additional keywords given, a TimeSeriesData object will be
+        created with all potential datasets created by the simulation.
+
+        Outputs can be gather by specifying a time or redshift range
+        (or combination of time and redshift), with a specific list of
+        times or redshifts, a range of cycle numbers (for cycle based
+        output), or by simply searching all subdirectories within the
+        simulation directory.
+
+        time_data : bool
+            Whether or not to include time outputs when gathering
+            datasets for time series.
+            Default: True.
+        redshift_data : bool
+            Whether or not to include redshift outputs when gathering
+            datasets for time series.
+            Default: True.
+        initial_time : float
+            The earliest time for outputs to be included.  If None,
+            the initial time of the simulation is used.  This can be
+            used in combination with either final_time or
+            final_redshift.
+            Default: None.
+        final_time : float
+            The latest time for outputs to be included.  If None,
+            the final time of the simulation is used.  This can be
+            used in combination with either initial_time or
+            initial_redshift.
+            Default: None.
+        times : array_like
+            A list of times for which outputs will be found.
+            Default: None.
+        time_units : str
+            The time units used for requesting outputs by time.
+            Default: '1' (code units).
+        initial_redshift : float
+            The earliest redshift for outputs to be included.  If None,
+            the initial redshift of the simulation is used.  This can be
+            used in combination with either final_time or
+            final_redshift.
+            Default: None.
+        final_time : float
+            The latest redshift for outputs to be included.  If None,
+            the final redshift of the simulation is used.  This can be
+            used in combination with either initial_time or
+            initial_redshift.
+            Default: None.
+        redshifts : array_like
+            A list of redshifts for which outputs will be found.
+            Default: None.
+        initial_cycle : float
+            The earliest cycle for outputs to be included.  If None,
+            the initial cycle of the simulation is used.  This can
+            only be used with final_cycle.
+            Default: None.
+        final_cycle : float
+            The latest cycle for outputs to be included.  If None,
+            the final cycle of the simulation is used.  This can
+            only be used in combination with initial_cycle.
+            Default: None.
+        tolerance : float
+            Used in combination with "times" or "redshifts" keywords,
+            this is the tolerance within which outputs are accepted
+            given the requested times or redshifts.  If None, the
+            nearest output is always taken.
+            Default: None.
+        find_outputs : bool
+            If True, subdirectories within the GlobalDir directory are
+            searched one by one for datasets.  Time and redshift
+            information are gathered by temporarily instantiating each
+            dataset.  This can be used when simulation data was created
+            in a non-standard way, making it difficult to guess the
+            corresponding time and redshift information.
+            Default: False.
+        parallel : bool/int
+            If True, the generated TimeSeriesData will divide the work
+            such that a single processor works on each dataset.  If an
+            integer is supplied, the work will be divided into that
+            number of jobs.
+            Default: True.
+
+        Examples
+        --------
+        >>> es.get_time_series(initial_redshift=10, final_time=13.7,
+                               time_units='Gyr', redshift_data=False)
+
+        >>> es.get_time_series(redshifts=[3, 2, 1, 0])
+
+        >>> es.get_time_series(final_cycle=100000)
+
+        >>> es.get_time_series(find_outputs=True)
+
+        >>> # after calling get_time_series
+        >>> for pf in es.piter():
+        >>>     pc = PlotCollection(pf, 'c')
+        >>>     pc.add_projection('Density', 0)
+        >>>     pc.save()
+
+        """
+
+        if (initial_redshift is not None or \
+            final_redshift is not None) and \
+            not self.cosmological_simulation:
+            mylog.error('An initial or final redshift has been given for a noncosmological simulation.')
+            return
+
+        if find_outputs:
+            my_outputs = self._find_outputs()
+
+        else:
+            if time_data and redshift_data:
+                my_all_outputs = self.all_outputs
+            elif time_data:
+                my_all_outputs = self.all_time_outputs
+            elif redshift_data:
+                my_all_outputs = self.all_redshift_outputs
+            else:
+                mylog.error('Both time_data and redshift_data are False.')
+                return
+
+            if times is not None:
+                my_outputs = self._get_outputs_by_time(times, tolerance=tolerance,
+                                                       outputs=my_all_outputs,
+                                                       time_units=time_units)
+
+            elif redshifts is not None:
+                my_outputs = self._get_outputs_by_redshift(redshifts, tolerance=tolerance,
+                                                           outputs=my_all_outputs)
+
+            elif initial_cycle is not None or final_cycle is not None:
+                if initial_cycle is None:
+                    initial_cycle = 0
+                else:
+                    initial_cycle = max(initial_cycle, 0)
+                if final_cycle is None:
+                    final_cycle = self.parameters['StopCycle']
+                else:
+                    final_cycle = min(final_cycle, self.parameters['StopCycle'])
+                my_outputs = my_all_outputs[int(ceil(float(initial_cycle) /
+                                                     self.parameters['CycleSkipDataDump'])):
+                                            (final_cycle /  self.parameters['CycleSkipDataDump'])+1]
+
+            else:
+                if initial_time is not None:
+                    my_initial_time = initial_time / self.time_units[time_units]
+                elif initial_redshift is not None:
+                    my_initial_time = self.enzo_cosmology.ComputeTimeFromRedshift(initial_redshift) / \
+                        self.enzo_cosmology.TimeUnits
+                else:
+                    my_initial_time = self.initial_time
+
+                if final_time is not None:
+                    my_final_time = final_time / self.time_units[time_units]
+                elif final_redshift is not None:
+                    my_final_time = self.enzo_cosmology.ComputeTimeFromRedshift(final_redshift) / \
+                        self.enzo_cosmology.TimeUnits
+                else:
+                    my_final_time = self.final_time
+                    
+                my_times = na.array(map(lambda a:a['time'], my_all_outputs))
+                my_indices = na.digitize([my_initial_time, my_final_time], my_times)
+                if my_initial_time == my_times[my_indices[0] - 1]: my_indices[0] -= 1
+                my_outputs = my_all_outputs[my_indices[0]:my_indices[1]]
+
+        TimeSeriesData.__init__(self, outputs=[output['filename'] for output in my_outputs],
+                                parallel=parallel)
+        mylog.info("%d outputs loaded into time series." % len(my_outputs))
+
+    def _parse_parameter_file(self):
+        """
+        Parses the parameter file and establishes the various
+        dictionaries.
+        """
+
+        self.conversion_factors = {}
+        redshift_outputs = []
+
+        # Let's read the file
+        lines = open(self.parameter_filename).readlines()
+        for line in (l.strip() for l in lines):
+            if '#' in line: line = line[0:line.find('#')]
+            if '//' in line: line = line[0:line.find('//')]
+            if len(line) < 2: continue
+            param, vals = (i.strip() for i in line.split("="))
+            # First we try to decipher what type of value it is.
+            vals = vals.split()
+            # Special case approaching.
+            if "(do" in vals: vals = vals[:1]
+            if len(vals) == 0:
+                pcast = str # Assume NULL output
+            else:
+                v = vals[0]
+                # Figure out if it's castable to floating point:
+                try:
+                    float(v)
+                except ValueError:
+                    pcast = str
+                else:
+                    if any("." in v or "e+" in v or "e-" in v for v in vals):
+                        pcast = float
+                    elif v == "inf":
+                        pcast = str
+                    else:
+                        pcast = int
+            # Now we figure out what to do with it.
+            if param.endswith("Units") and not param.startswith("Temperature"):
+                dataType = param[:-5]
+                # This one better be a float.
+                self.conversion_factors[dataType] = float(vals[0])
+            if param.startswith("CosmologyOutputRedshift["):
+                index = param[param.find("[")+1:param.find("]")]
+                redshift_outputs.append({'index':int(index), 'redshift':float(vals[0])})
+            elif len(vals) == 0:
+                vals = ""
+            elif len(vals) == 1:
+                vals = pcast(vals[0])
+            else:
+                vals = na.array([pcast(i) for i in vals if i != "-99999"])
+            self.parameters[param] = vals
+        self.refine_by = self.parameters["RefineBy"]
+        self.dimensionality = self.parameters["TopGridRank"]
+        if self.dimensionality > 1:
+            self.domain_dimensions = self.parameters["TopGridDimensions"]
+            if len(self.domain_dimensions) < 3:
+                tmp = self.domain_dimensions.tolist()
+                tmp.append(1)
+                self.domain_dimensions = na.array(tmp)
+            self.domain_left_edge = na.array(self.parameters["DomainLeftEdge"],
+                                             "float64").copy()
+            self.domain_right_edge = na.array(self.parameters["DomainRightEdge"],
+                                             "float64").copy()
+        else:
+            self.domain_left_edge = na.array(self.parameters["DomainLeftEdge"],
+                                             "float64")
+            self.domain_right_edge = na.array(self.parameters["DomainRightEdge"],
+                                             "float64")
+            self.domain_dimensions = na.array([self.parameters["TopGridDimensions"],1,1])
+
+        if self.parameters["ComovingCoordinates"]:
+            cosmo_attr = {'omega_lambda': 'CosmologyOmegaLambdaNow',
+                          'omega_matter': 'CosmologyOmegaMatterNow',
+                          'hubble_constant': 'CosmologyHubbleConstantNow',
+                          'initial_redshift': 'CosmologyInitialRedshift',
+                          'final_redshift': 'CosmologyFinalRedshift'}
+            self.cosmological_simulation = 1
+            for a, v in cosmo_attr.items():
+                if not v in self.parameters:
+                    raise MissingParameter(self.parameter_filename, v)
+                setattr(self, a, self.parameters[v])
+        else:
+            self.omega_lambda = self.omega_matter = \
+                self.hubble_constant = self.cosmological_simulation = 0.0
+
+        # make list of redshift outputs
+        self.all_redshift_outputs = []
+        if not self.cosmological_simulation: return
+        for output in redshift_outputs:
+            output['filename'] = os.path.join(self.parameters['GlobalDir'],
+                                              "%s%04d" % (self.parameters['RedshiftDumpDir'],
+                                                          output['index']),
+                                              "%s%04d" % (self.parameters['RedshiftDumpName'],
+                                                          output['index']))
+            del output['index']
+        self.all_redshift_outputs = redshift_outputs
+
+    def _calculate_redshift_dump_times(self):
+        "Calculates time from redshift of redshift outputs."
+
+        if not self.cosmological_simulation: return
+        for output in self.all_redshift_outputs:
+            output['time'] = self.enzo_cosmology.ComputeTimeFromRedshift(output['redshift']) / \
+                self.enzo_cosmology.TimeUnits
+
+    def _calculate_time_outputs(self):
+        "Calculate time outputs and their redshifts if cosmological."
+
+        if self.final_time is None or \
+            not 'dtDataDump' in self.parameters or \
+            self.parameters['dtDataDump'] <= 0.0: return []
+
+        self.all_time_outputs = []
+        index = 0
+        current_time = self.initial_time
+        while current_time <= self.final_time + self.parameters['dtDataDump']:
+            filename = os.path.join(self.parameters['GlobalDir'],
+                                    "%s%04d" % (self.parameters['DataDumpDir'], index),
+                                    "%s%04d" % (self.parameters['DataDumpName'], index))
+
+            output = {'index': index, 'filename': filename, 'time': current_time}
+            output['time'] = min(output['time'], self.final_time)
+            if self.cosmological_simulation:
+                output['redshift'] = self.enzo_cosmology.ComputeRedshiftFromTime(
+                    current_time * self.enzo_cosmology.TimeUnits)
+
+            self.all_time_outputs.append(output)
+            if na.abs(self.final_time - current_time) / self.final_time < 1e-4: break
+            current_time += self.parameters['dtDataDump']
+            index += 1
+
+    def _calculate_cycle_outputs(self):
+        "Calculate cycle outputs."
+
+        mylog.warn('Calculating cycle outputs.  Dataset times will be unavailable.')
+
+        if self.stop_cycle is None or \
+            not 'CycleSkipDataDump' in self.parameters or \
+            self.parameters['CycleSkipDataDump'] <= 0.0: return []
+
+        self.all_time_outputs = []
+        index = 0
+        for cycle in range(0, self.stop_cycle+1, self.parameters['CycleSkipDataDump']):
+            filename = os.path.join(self.parameters['GlobalDir'],
+                                    "%s%04d" % (self.parameters['DataDumpDir'], index),
+                                    "%s%04d" % (self.parameters['DataDumpName'], index))
+
+            output = {'index': index, 'filename': filename, 'cycle': cycle}
+            self.all_time_outputs.append(output)
+            index += 1
+
+    def _get_all_outputs(self):
+        "Get all potential datasets and combine into a time-sorted list."
+
+        if self.parameters['dtDataDump'] > 0 and \
+            self.parameters['CycleSkipDataDump'] > 0:
+            mylog.info("Simulation %s has both dtDataDump and CycleSkipDataDump set." % self.parameter_filename )
+            mylog.info("    Unable to calculate datasets.  Attempting to search in the current directory")
+            self.all_time_outputs = self._find_outputs()
+
+        # Get all time or cycle outputs.
+        elif self.parameters['CycleSkipDataDump'] > 0:
+            self._calculate_cycle_outputs()
+        else:
+            self._calculate_time_outputs()
+
+        # Calculate times for redshift outputs.
+        self._calculate_redshift_dump_times()
+
+        self.all_outputs = self.all_time_outputs + self.all_redshift_outputs
+        if self.parameters['CycleSkipDataDump'] <= 0:
+            self.all_outputs.sort(key=lambda obj:obj['time'])
+
+        mylog.info("Total datasets: %d." % len(self.all_outputs))
+
+    def _calculate_simulation_bounds(self):
+        """
+        Figure out the starting and stopping time and redshift for the simulation.
+        """
+
+        if 'StopCycle' in self.parameters:
+            self.stop_cycle = self.parameters['StopCycle']
+
+        # Convert initial/final redshifts to times.
+        if self.cosmological_simulation:
+            # Instantiate EnzoCosmology object for units and time conversions.
+            self.enzo_cosmology = EnzoCosmology(HubbleConstantNow=
+                                                (100.0 * self.parameters['CosmologyHubbleConstantNow']),
+                                                OmegaMatterNow=self.parameters['CosmologyOmegaMatterNow'],
+                                                OmegaLambdaNow=self.parameters['CosmologyOmegaLambdaNow'],
+                                                InitialRedshift=self.parameters['CosmologyInitialRedshift'])
+            self.initial_time = self.enzo_cosmology.ComputeTimeFromRedshift(self.initial_redshift) / \
+                self.enzo_cosmology.TimeUnits
+            self.final_time = self.enzo_cosmology.ComputeTimeFromRedshift(self.final_redshift) / \
+                self.enzo_cosmology.TimeUnits
+
+        # If not a cosmology simulation, figure out the stopping criteria.
+        else:
+            if 'InitialTime' in self.parameters:
+                self.initial_time = self.parameters['InitialTime']
+            else:
+                self.initial_time = 0.
+
+            if 'StopTime' in self.parameters:
+                self.final_time = self.parameters['StopTime']
+            else:
+                self.final_time = None
+            if not ('StopTime' in self.parameters or
+                    'StopCycle' in self.parameters):
+                raise NoStoppingCondition(self.parameter_filename)
+            if self.final_time is None:
+                mylog.warn('Simulation %s has no stop time set, stopping condition will be based only on cycles.' %
+                           self.parameter_filename)
+
+    def _set_parameter_defaults(self):
+        "Set some default parameters to avoid problems if they are not in the parameter file."
+
+        self.parameters['GlobalDir'] = self.directory
+        self.parameters['DataDumpName'] = "data"
+        self.parameters['DataDumpDir'] = "DD"
+        self.parameters['RedshiftDumpName'] = "RedshiftOutput"
+        self.parameters['RedshiftDumpDir'] = "RD"
+        self.parameters['ComovingCoordinates'] = 0
+        self.parameters['TopGridRank'] = 3
+        self.parameters['DomainLeftEdge'] = na.zeros(self.parameters['TopGridRank'])
+        self.parameters['DomainRightEdge'] = na.ones(self.parameters['TopGridRank'])
+        self.parameters['Refineby'] = 2 # technically not the enzo default
+        self.parameters['StopCycle'] = 100000
+        self.parameters['dtDataDump'] = 0.
+        self.parameters['CycleSkipDataDump'] = 0.
+        self.parameters['TimeUnits'] = 1.
+
+    def _set_time_units(self):
+        """
+        Set up a dictionary of time units conversions.
+        """
+
+        self.time_units = {}
+        if self.cosmological_simulation:
+            self.parameters['TimeUnits'] = 2.52e17 / na.sqrt(self.omega_matter) \
+                / self.hubble_constant / (1 + self.initial_redshift)**1.5
+        self.time_units['1'] = 1.
+        self.time_units['seconds'] = self.parameters['TimeUnits']
+        self.time_units['years'] = self.time_units['seconds'] / (365*3600*24.0)
+        self.time_units['days']  = self.time_units['seconds'] / (3600*24.0)
+        self.time_units['Myr'] = self.time_units['years'] / 1.0e6
+        self.time_units['Gyr']  = self.time_units['years'] / 1.0e9
+
+    def _find_outputs(self):
+        """
+        Search for directories matching the data dump keywords.
+        If found, get dataset times py opening the pf.
+        """
+
+        # look for time outputs.
+        potential_outputs = glob.glob(os.path.join(self.parameters['GlobalDir'],
+                                                   "%s*" % self.parameters['DataDumpDir'])) + \
+                            glob.glob(os.path.join(self.parameters['GlobalDir'],
+                                                   "%s*" % self.parameters['RedshiftDumpDir']))
+        time_outputs = []
+        mylog.info("Checking %d potential time outputs." % 
+                   len(potential_outputs))
+
+        for output in potential_outputs:
+            if self.parameters['DataDumpDir'] in output:
+                dir_key = self.parameters['DataDumpDir']
+                output_key = self.parameters['DataDumpName']
+            else:
+                dir_key = self.parameters['RedshiftDumpDir']
+                output_key = self.parameters['RedshiftDumpName']
+            index = output[output.find(dir_key) + len(dir_key):]
+            filename = os.path.join(self.parameters['GlobalDir'],
+                                    "%s%s" % (dir_key, index),
+                                    "%s%s" % (output_key, index))
+            if os.path.exists(filename):
+                try:
+                    pf = load(filename)
+                    if pf is not None:
+                        time_outputs.append({'filename': filename, 'time': pf.current_time})
+                        if pf.cosmological_simulation:
+                            time_outputs[-1]['redshift'] = pf.current_redshift
+                except YTOutputNotIdentified:
+                    mylog.error('Failed to load %s' % filename)
+
+        mylog.info("Located %d time outputs." % len(time_outputs))
+        time_outputs.sort(key=lambda obj: obj['time'])
+        return time_outputs
+
+    def _get_outputs_by_key(self, key, values, tolerance=None, outputs=None):
+        r"""Get datasets at or near to given values.
+        
+        Parameters
+        ----------
+        key: str
+            The key by which to retrieve outputs, usually 'time' or
+            'redshift'.
+        values: array_like
+            A list of values, given as floats.
+        tolerance : float
+            If not None, do not return a dataset unless the value is
+            within the tolerance value.  If None, simply return the
+            nearest dataset.
+            Default: None.
+        outputs : list
+            The list of outputs from which to choose.  If None,
+            self.all_outputs is used.
+            Default: None.
+        
+        Examples
+        --------
+        >>> datasets = es.get_outputs_by_key('redshift', [0, 1, 2], tolerance=0.1)
+        
+        """
+
+        values = ensure_list(values)
+        if outputs is None:
+            outputs = self.all_outputs
+        my_outputs = []
+        for value in values:
+            outputs.sort(key=lambda obj:na.fabs(value - obj[key]))
+            if (tolerance is None or na.abs(value - outputs[0][key]) <= tolerance) \
+                    and outputs[0] not in my_outputs:
+                my_outputs.append(outputs[0])
+            else:
+                mylog.error("No dataset added for %s = %f." % (key, value))
+
+        outputs.sort(key=lambda obj: obj['time'])
+        return my_outputs
+
+    def _get_outputs_by_redshift(self, redshifts, tolerance=None, outputs=None):
+        r"""Get datasets at or near to given redshifts.
+        
+        Parameters
+        ----------
+        redshifts: array_like
+            A list of redshifts, given as floats.
+        tolerance : float
+            If not None, do not return a dataset unless the value is
+            within the tolerance value.  If None, simply return the
+            nearest dataset.
+            Default: None.
+        outputs : list
+            The list of outputs from which to choose.  If None,
+            self.all_outputs is used.
+            Default: None.
+        
+        Examples
+        --------
+        >>> datasets = es.get_outputs_by_redshift([0, 1, 2], tolerance=0.1)
+        
+        """
+
+        return self._get_outputs_by_key('redshift', redshifts, tolerance=tolerance,
+                                     outputs=outputs)
+
+    def _get_outputs_by_time(self, times, tolerance=None, outputs=None,
+                             time_units='1'):
+        r"""Get datasets at or near to given times.
+        
+        Parameters
+        ----------
+        times: array_like
+            A list of times, given in code units as floats.
+        tolerance : float
+            If not None, do not return a dataset unless the time is
+            within the tolerance value.  If None, simply return the
+            nearest dataset.
+            Default = None.
+        outputs : list
+            The list of outputs from which to choose.  If None,
+            self.all_outputs is used.
+            Default: None.
+        time_units : str
+            The units of the list of times.
+            Default: '1' (code units).
+        
+        Examples
+        --------
+        >>> datasets = es.get_outputs_by_time([600, 500, 400], tolerance=10.)
+        
+        """
+
+        times = na.array(times) / self.time_units[time_units]
+        return self._get_outputs_by_key('time', times, tolerance=tolerance,
+                                        outputs=outputs)
+


diff -r 3f114eed5c32b4557b823733e3a100c0dd76edcb -r 1f6b809592d82ae9be010b236457849e22b8aa23 yt/mods.py
--- a/yt/mods.py
+++ b/yt/mods.py
@@ -67,7 +67,8 @@
     add_quantity, quantity_info
 
 from yt.frontends.enzo.api import \
-    EnzoStaticOutput, EnzoStaticOutputInMemory, EnzoFieldInfo, \
+    EnzoStaticOutput, EnzoStaticOutputInMemory, \
+    EnzoSimulation, EnzoFieldInfo, \
     add_enzo_field, add_enzo_1d_field, add_enzo_2d_field
 
 from yt.frontends.castro.api import \
@@ -128,7 +129,8 @@
 for name, cls in callback_registry.items():
     exec("%s = cls" % name)
 
-from yt.convenience import load, projload
+from yt.convenience import \
+    load, projload, simulation
 
 # Import some helpful math utilities
 from yt.utilities.math_utils import \


diff -r 3f114eed5c32b4557b823733e3a100c0dd76edcb -r 1f6b809592d82ae9be010b236457849e22b8aa23 yt/utilities/exceptions.py
--- a/yt/utilities/exceptions.py
+++ b/yt/utilities/exceptions.py
@@ -67,3 +67,37 @@
         if self.obj_type == "slice":
             s += "  It may lie on a grid face.  Try offsetting slightly."
         return s
+
+class YTSimulationNotIdentified(YTException):
+    def __init__(self, sim_type):
+        YTException.__init__(self)
+        self.sim_type = sim_type
+
+    def __str__(self):
+        return "Simulation time-series type %s not defined." % self.sim_type
+
+class AmbiguousOutputs(YTException):
+    def __init__(self, pf):
+        YTException.__init__(self, pf)
+
+    def __str__(self):
+        return "Simulation %s has both dtDataDump and CycleSkipDataDump set.  Unable to calculate datasets." % \
+            self.pf
+
+class MissingParameter(YTException):
+    def __init__(self, pf, parameter):
+        YTException.__init__(self, pf)
+        self.parameter = parameter
+
+    def __str__(self):
+        return "Parameter file %s is missing %s parameter." % \
+            (self.pf, self.parameter)
+
+class NoStoppingCondition(YTException):
+    def __init__(self, pf):
+        YTException.__init__(self, pf)
+
+    def __str__(self):
+        return "Simulation %s has no stopping condition.  StopTime or StopCycle should be set." % \
+            self.pf
+


diff -r 3f114eed5c32b4557b823733e3a100c0dd76edcb -r 1f6b809592d82ae9be010b236457849e22b8aa23 yt/utilities/parallel_tools/parallel_analysis_interface.py
--- a/yt/utilities/parallel_tools/parallel_analysis_interface.py
+++ b/yt/utilities/parallel_tools/parallel_analysis_interface.py
@@ -343,7 +343,6 @@
 def parallel_objects(objects, njobs = 0, storage = None, barrier = True):
     if not parallel_capable:
         njobs = 1
-        mylog.warn("parallel_objects() is being used when parallel_capable is false. The loop is not being run in parallel. This may not be what was expected.")
     my_communicator = communication_system.communicators[-1]
     my_size = my_communicator.size
     if njobs <= 0:


diff -r 3f114eed5c32b4557b823733e3a100c0dd76edcb -r 1f6b809592d82ae9be010b236457849e22b8aa23 yt/utilities/parameter_file_storage.py
--- a/yt/utilities/parameter_file_storage.py
+++ b/yt/utilities/parameter_file_storage.py
@@ -33,6 +33,7 @@
     parallel_simple_proxy
 
 output_type_registry = {}
+simulation_time_series_registry = {}
 _field_names = ('hash', 'bn', 'fp', 'tt', 'ctid', 'class_name', 'last_seen')
 
 class NoParameterShelf(Exception):


diff -r 3f114eed5c32b4557b823733e3a100c0dd76edcb -r 1f6b809592d82ae9be010b236457849e22b8aa23 yt/visualization/volume_rendering/camera.py
--- a/yt/visualization/volume_rendering/camera.py
+++ b/yt/visualization/volume_rendering/camera.py
@@ -214,8 +214,8 @@
                                      unit_vectors[1]*width[1],
                                      unit_vectors[2]*width[2]])
         self.origin = center - 0.5*na.dot(width,unit_vectors)
-        self.back_center =  center - 0.5*width[0]*unit_vectors[2]
-        self.front_center = center + 0.5*width[0]*unit_vectors[2]         
+        self.back_center =  center - 0.5*width[2]*unit_vectors[2]
+        self.front_center = center + 0.5*width[2]*unit_vectors[2]         
 
     def look_at(self, new_center, north_vector = None):
         r"""Change the view direction based on a new focal point.


diff -r 3f114eed5c32b4557b823733e3a100c0dd76edcb -r 1f6b809592d82ae9be010b236457849e22b8aa23 yt/visualization/volume_rendering/grid_partitioner.py
--- a/yt/visualization/volume_rendering/grid_partitioner.py
+++ b/yt/visualization/volume_rendering/grid_partitioner.py
@@ -41,7 +41,8 @@
 class HomogenizedVolume(ParallelAnalysisInterface):
     bricks = None
     def __init__(self, fields = "Density", source = None, pf = None,
-                 log_fields = None, no_ghost = False):
+                 log_fields = None, no_ghost = False,
+                 max_level = 48):
         # Typically, initialized as hanging off a hierarchy.  But, not always.
         ParallelAnalysisInterface.__init__(self)
         self.no_ghost = no_ghost
@@ -54,6 +55,7 @@
         else:
             log_fields = [self.pf.field_info[field].take_log
                          for field in self.fields]
+        self.max_level = max_level
         self.log_fields = log_fields
 
     def traverse(self, back_point, front_point, image):
@@ -84,8 +86,13 @@
         PP = ProtoPrism(grid.id, grid.LeftEdge, grid.RightEdge, GF)
 
         pgs = []
+        cm = grid.child_mask.copy()
+        if grid.Level > self.max_level:
+            return pgs
+        elif grid.Level == self.max_level:
+            cm[:] = 1
         for P in PP.sweep(0):
-            sl = P.get_brick(grid.LeftEdge, grid.dds, grid.child_mask)
+            sl = P.get_brick(grid.LeftEdge, grid.dds, cm)
             if len(sl) == 0: continue
             dd = [d[sl[0][0]:sl[0][1]+1,
                     sl[1][0]:sl[1][1]+1,



https://bitbucket.org/yt_analysis/yt/changeset/cd3ad30dcf40/
changeset:   cd3ad30dcf40
branch:      yt
user:        MatthewTurk
date:        2012-06-17 19:54:18
summary:     Turning off the shutdown for now.
affected #:  1 file

diff -r 3f114eed5c32b4557b823733e3a100c0dd76edcb -r cd3ad30dcf40fa55519318dc0eb1de63678f0035 yt/gui/reason/html/app/controller/ServerCommunication.js
--- a/yt/gui/reason/html/app/controller/ServerCommunication.js
+++ b/yt/gui/reason/html/app/controller/ServerCommunication.js
@@ -89,10 +89,10 @@
                             reason.fireEvent("payloadreceived", payload);
                     });
                 }
-                else if (!a.status) {
+                /*else if (!a.status) {
                     reason.fireEvent("stopheartbeat");
                     Ext.Msg.alert("Error", "Error talking to server.  Shutting down.");
-                }
+                }*/
                 return true;
             }
         );



https://bitbucket.org/yt_analysis/yt/changeset/d33c8b031561/
changeset:   d33c8b031561
branch:      yt
user:        MatthewTurk
date:        2012-06-17 19:54:39
summary:     Merging
affected #:  17 files

diff -r cd3ad30dcf40fa55519318dc0eb1de63678f0035 -r d33c8b031561083ea6176b026e7c6ae1f420b3f8 doc/install_script.sh
--- a/doc/install_script.sh
+++ b/doc/install_script.sh
@@ -353,7 +353,7 @@
 
 # Now we dump all our SHA512 files out.
 
-echo '2c1933ab31246b4f4eba049d3288156e0a72f1730604e3ed7357849967cdd329e4647cf236c9442ecfb06d0aff03e6fc892a7ba2a5c1cf5c011b7ab9c619acec  Cython-0.16.tar.gz ' > Cython-0.16.tar.gz.sha512
+echo '2c1933ab31246b4f4eba049d3288156e0a72f1730604e3ed7357849967cdd329e4647cf236c9442ecfb06d0aff03e6fc892a7ba2a5c1cf5c011b7ab9c619acec  Cython-0.16.tar.gz' > Cython-0.16.tar.gz.sha512
 echo 'b8a12bf05b3aafa71135e47da81440fd0f16a4bd91954bc5615ad3d3b7f9df7d5a7d5620dc61088dc6b04952c5c66ebda947a4cfa33ed1be614c8ca8c0f11dff  PhiloGL-1.4.2.zip' > PhiloGL-1.4.2.zip.sha512
 echo '44eea803870a66ff0bab08d13a8b3388b5578ebc1c807d1d9dca0a93e6371e91b15d02917a00b3b20dc67abb5a21dabaf9b6e9257a561f85eeff2147ac73b478  PyX-0.11.1.tar.gz' > PyX-0.11.1.tar.gz.sha512
 echo '1a754d560bfa433f0960ab3b5a62edb5f291be98ec48cf4e5941fa5b84139e200b87a52efbbd6fa4a76d6feeff12439eed3e7a84db4421940d1bbb576f7a684e  Python-2.7.2.tgz' > Python-2.7.2.tgz.sha512


diff -r cd3ad30dcf40fa55519318dc0eb1de63678f0035 -r d33c8b031561083ea6176b026e7c6ae1f420b3f8 yt/analysis_modules/halo_profiler/api.py
--- a/yt/analysis_modules/halo_profiler/api.py
+++ b/yt/analysis_modules/halo_profiler/api.py
@@ -34,5 +34,4 @@
 from .multi_halo_profiler import \
     HaloProfiler, \
     FakeProfile, \
-    get_halo_sphere, \
     standard_fields


diff -r cd3ad30dcf40fa55519318dc0eb1de63678f0035 -r d33c8b031561083ea6176b026e7c6ae1f420b3f8 yt/analysis_modules/halo_profiler/centering_methods.py
--- a/yt/analysis_modules/halo_profiler/centering_methods.py
+++ b/yt/analysis_modules/halo_profiler/centering_methods.py
@@ -43,14 +43,14 @@
 @add_function("Min_Dark_Matter_Density")
 def find_minimum_dm_density(data):
     ma, maxi, mx, my, mz, mg = data.quantities['MinLocation']('Dark_Matter_Density',
-                                                              lazy_reader=False,
+                                                              lazy_reader=True,
                                                               preload=False)
     return (mx, my, mz)
 
 @add_function("Max_Dark_Matter_Density")
 def find_maximum_dm_density(data):
     ma, maxi, mx, my, mz, mg = data.quantities['MaxLocation']('Dark_Matter_Density',
-                                                              lazy_reader=False,
+                                                              lazy_reader=True,
                                                               preload=False)
     return (mx, my, mz)
 
@@ -58,7 +58,7 @@
 def find_CoM_dm_density(data):
    dc_x, dc_y, dc_z = data.quantities['CenterOfMass'](use_cells=False, 
                                                       use_particles=True,
-                                                      lazy_reader=False,
+                                                      lazy_reader=True,
                                                       preload=False)
    return (dc_x, dc_y, dc_z)
 
@@ -67,14 +67,14 @@
 @add_function("Min_Gas_Density")
 def find_minimum_gas_density(data):
     ma, maxi, mx, my, mz, mg = data.quantities['MinLocation']('Density',
-                                                              lazy_reader=False,
+                                                              lazy_reader=True,
                                                               preload=False)
     return (mx, my, mz)
 
 @add_function("Max_Gas_Density")
 def find_maximum_gas_density(data):
     ma, maxi, mx, my, mz, mg = data.quantities['MaxLocation']('Density',
-                                                              lazy_reader=False,
+                                                              lazy_reader=True,
                                                               preload=False)
     return (mx, my, mz)
 
@@ -82,7 +82,7 @@
 def find_CoM_gas_density(data):
    dc_x, dc_y, dc_z = data.quantities['CenterOfMass'](use_cells=True, 
                                                       use_particles=False,
-                                                      lazy_reader=False,
+                                                      lazy_reader=True,
                                                       preload=False)
    return (dc_x, dc_y, dc_z)
 
@@ -91,14 +91,14 @@
 @add_function("Min_Total_Density")
 def find_minimum_total_density(data):
     ma, maxi, mx, my, mz, mg = data.quantities['MinLocation']('Matter_Density',
-                                                              lazy_reader=False,
+                                                              lazy_reader=True,
                                                               preload=False)
     return (mx, my, mz)
 
 @add_function("Max_Total_Density")
 def find_maximum_total_density(data):
     ma, maxi, mx, my, mz, mg = data.quantities['MaxLocation']('Matter_Density',
-                                                              lazy_reader=False,
+                                                              lazy_reader=True,
                                                               preload=False)
     return (mx, my, mz)
 
@@ -106,7 +106,7 @@
 def find_CoM_total_density(data):
    dc_x, dc_y, dc_z = data.quantities['CenterOfMass'](use_cells=True, 
                                                       use_particles=True,
-                                                      lazy_reader=False,
+                                                      lazy_reader=True,
                                                       preload=False)
    return (dc_x, dc_y, dc_z)
 
@@ -115,14 +115,14 @@
 @add_function("Min_Temperature")
 def find_minimum_temperature(data):
     ma, mini, mx, my, mz, mg = data.quantities['MinLocation']('Temperature',
-                                                              lazy_reader=False,
+                                                              lazy_reader=True,
                                                               preload=False)
     return (mx, my, mz)
 
 @add_function("Max_Temperature")
 def find_maximum_temperature(data):
     ma, maxi, mx, my, mz, mg = data.quantities['MaxLocation']('Temperature',
-                                                              lazy_reader=False,
+                                                              lazy_reader=True,
                                                               preload=False)
     return (mx, my, mz)
 


diff -r cd3ad30dcf40fa55519318dc0eb1de63678f0035 -r d33c8b031561083ea6176b026e7c6ae1f420b3f8 yt/analysis_modules/halo_profiler/multi_halo_profiler.py
--- a/yt/analysis_modules/halo_profiler/multi_halo_profiler.py
+++ b/yt/analysis_modules/halo_profiler/multi_halo_profiler.py
@@ -42,6 +42,8 @@
     centering_registry
 from yt.data_objects.field_info_container import \
     add_field
+from yt.data_objects.static_output import \
+    StaticOutput
 
 from yt.utilities.parallel_tools.parallel_analysis_interface import \
     ParallelAnalysisInterface, \
@@ -64,7 +66,7 @@
                                          dm_only=False, resize=True, 
                                          fancy_padding=True, rearrange=True),
                  halo_radius=None, radius_units='1', n_profile_bins=50,
-                 recenter = None,
+                 recenter=None,
                  profile_output_dir='radial_profiles', projection_output_dir='projections',
                  projection_width=8.0, projection_width_units='mpc', project_at_level='max',
                  velocity_center=['bulk', 'halo'], filter_quantities=['id', 'center', 'r_max'], 
@@ -111,8 +113,32 @@
             Args given with call to halo finder function.  Default: None.
         halo_finder_kwargs : dict
             kwargs given with call to halo finder function. Default: None.
-        recenter : {string, function
-            The name of a function that recenters the halo for analysis.
+        recenter : {string, function}
+            The exact location of the sphere center can significantly affect 
+            radial profiles.  The halo center loaded by the HaloProfiler will 
+            typically be the dark matter center of mass calculated by a halo 
+            finder.  However, this may not be the best location for centering 
+            profiles of baryon quantities.  For example, one may want to center 
+            on the maximum density.
+            If recenter is given as a string, one of the existing recentering 
+            functions will be used:
+                Min_Dark_Matter_Density : location of minimum dark matter density
+                Max_Dark_Matter_Density : location of maximum dark matter density
+                CoM_Dark_Matter_Density : dark matter center of mass
+                Min_Gas_Density : location of minimum gas density
+                Max_Gas_Density : location of maximum gas density
+                CoM_Gas_Density : gas center of mass
+                Min_Total_Density : location of minimum total density
+                Max_Total_Density : location of maximum total density
+                CoM_Total_Density : total center of mass
+                Min_Temperature : location of minimum temperature
+                Max_Temperature : location of maximum temperature
+            Alternately, a function can be supplied for custom recentering.
+            The function should take only one argument, a sphere object.
+                Example function:
+                    def my_center_of_mass(data):
+                       my_x, my_y, my_z = data.quantities['CenterOfMass']()
+                       return (my_x, my_y, my_z)
             Default: None.
         halo_radius : float
             If no halo radii are provided in the halo list file, this
@@ -148,8 +174,7 @@
                 * ["bulk", "sphere"]: the bulk velocity of the sphere
                   centered on the halo center.
     	        * ["max", field]: the velocity of the cell that is the
-    	          location of the maximum of the field 
-                  specified (used only when halos set to single).
+    	          location of the maximum of the field specified.
         filter_quantities : array_like
             Quantities from the original halo list file to be written out in the 
             filtered list file.  Default: ['id','center'].
@@ -161,8 +186,8 @@
         
         Examples
         --------
-        >>> import yt.analysis_modules.halo_profiler.api as HP
-        >>> hp = HP.halo_profiler("DD0242/DD0242")
+        >>> from yt.analysis_modules.halo_profiler.api import *
+        >>> hp = HaloProfiler("RedshiftOutput0005/RD0005")
         
         """
         ParallelAnalysisInterface.__init__(self)
@@ -226,13 +251,9 @@
         # Option to recenter sphere someplace else.
         self.recenter = recenter
 
-        # Look for any field that might need to have the bulk velocity set.
+        # Flag for whether calculating halo bulk velocity is necessary.
         self._need_bulk_velocity = False
-        for field in [hp['field'] for hp in self.profile_fields]:
-            if 'Velocity' in field or 'Mach' in field:
-                self._need_bulk_velocity = True
-                break
-
+        
         # Check validity for VelocityCenter parameter which toggles how the 
         # velocity is zeroed out for radial velocity profiles.
         self.velocity_center = velocity_center[:]
@@ -250,15 +271,16 @@
                 mylog.error("Second value of VelocityCenter must be either 'halo' or 'sphere' if first value is 'bulk'.")
                 return None
         elif self.velocity_center[0] == 'max':
-            if self.halos is 'multiple':
-                mylog.error("Getting velocity center from a max field value only works with halos='single'.")
-                return None
+            mylog.info('Using position of max %s for velocity center.' % self.velocity_center[1])
         else:
             mylog.error("First value of parameter, VelocityCenter, must be either 'bulk' or 'max'.")
             return None
 
         # Create dataset object.
-        self.pf = load(self.dataset)
+        if isinstance(self.dataset, StaticOutput):
+            self.pf = self.dataset
+        else:
+            self.pf = load(self.dataset)
         self.pf.h
 
         # Figure out what max radius to use for profiling.
@@ -284,7 +306,7 @@
                 mylog.error("No halos loaded, there will be nothing to do.")
                 return None
         else:
-            mylog.error("I don't know whether to get halos from hop or from density maximum.  This should not have happened.")
+            mylog.error("Keyword, halos, must be either 'single' or 'multiple'.")
             return None
 
     def add_halo_filter(self, function, *args, **kwargs):
@@ -351,6 +373,10 @@
             
         """
 
+        # Check for any field that might need to have the bulk velocity set.
+        if 'Velocity' in field or 'Mach' in field:
+            self._need_bulk_velocity = True
+
         self.profile_fields.append({'field':field, 'weight_field':weight_field, 
                                     'accumulation':accumulation})
 
@@ -379,11 +405,15 @@
 
         """
 
+        # Check for any field that might need to have the bulk velocity set.
+        if 'Velocity' in field or 'Mach' in field:
+            self._need_bulk_velocity = True
+
         self.projection_fields.append({'field':field, 'weight_field':weight_field, 
                                        'cmap': cmap})
 
     @parallel_blocking_call
-    def make_profiles(self, filename=None, prefilters=None, **kwargs):
+    def make_profiles(self, filename=None, prefilters=None, njobs=-1):
         r"""Make radial profiles for all halos in the list.
         
         After all the calls to `add_profile`, this will trigger the actual
@@ -394,7 +424,7 @@
         filename : string
             If set, a file will be written with all of the filtered halos
             and the quantities returned by the filter functions.
-            Default=None.
+            Default: None.
         prefilters : array_like
             A single dataset can contain thousands or tens of thousands of
             halos. Significant time can be saved by not profiling halos
@@ -402,6 +432,11 @@
             Simple filters based on quantities provided in the initial
             halo list can be used to filter out unwanted halos using this
             parameter.
+            Default: None.
+        njobs : int
+            The number of jobs over which to split the profiling.  Set
+            to -1 so that each halo is done by a single processor.
+            Default: -1.
         
         Examples
         --------
@@ -454,7 +489,7 @@
 
         # Profile all halos.
         updated_halos = []
-        for halo in parallel_objects(self.all_halos, -1):
+        for halo in parallel_objects(self.all_halos, njobs=njobs):
             # Apply prefilters to avoid profiling unwanted halos.
             filter_result = True
             haloQuantities = {}
@@ -468,7 +503,8 @@
 
                 profile_filename = "%s/Halo_%04d_profile.dat" % (my_output_dir, halo['id'])
 
-                profiledHalo = self._get_halo_profile(halo, profile_filename, virial_filter=virial_filter)
+                profiledHalo = self._get_halo_profile(halo, profile_filename,
+                                                      virial_filter=virial_filter)
 
                 if profiledHalo is None:
                     continue
@@ -487,26 +523,26 @@
                 for quantity in self.filter_quantities:
                     if halo.has_key(quantity): haloQuantities[quantity] = halo[quantity]
 
-                self.filtered_halos.append(haloQuantities)
+                only_on_root(self.filtered_halos.append, haloQuantities)
 
             # If we've gotten this far down, this halo is good and we want
             # to keep it. But we need to communicate the recentering changes
             # to all processors (the root one in particular) without having
             # one task clobber the other.
-            updated_halos.append(halo)
-        
+            only_on_root(updated_halos.append, halo)
+
         # And here is where we bring it all together.
         updated_halos = self.comm.par_combine_object(updated_halos,
                             datatype="list", op="cat")
-        updated_halos.sort(key = lambda a:a['id'])
+        updated_halos.sort(key=lambda a:a['id'])
         self.all_halos = updated_halos
 
         self.filtered_halos = self.comm.par_combine_object(self.filtered_halos,
                             datatype="list", op="cat")
-        self.filtered_halos.sort(key = lambda a:a['id'])
+        self.filtered_halos.sort(key=lambda a:a['id'])
 
         if filename is not None:
-            self._write_filtered_halo_list(filename, **kwargs)
+            self._write_filtered_halo_list(filename)
 
     def _get_halo_profile(self, halo, filename, virial_filter=True,
             force_write=False):
@@ -529,31 +565,13 @@
                 return None
 
             # get a sphere object to profile
-            sphere = get_halo_sphere(halo, self.pf, recenter=self.recenter)
+            sphere = self._get_halo_sphere(halo)
             if sphere is None: return None
 
-            if self._need_bulk_velocity:
-                # Set bulk velocity to zero out radial velocity profiles.
-                if self.velocity_center[0] == 'bulk':
-                    if self.velocity_center[1] == 'halo':
-                        sphere.set_field_parameter('bulk_velocity', halo['velocity'])
-                    elif self.velocity_center[1] == 'sphere':
-                        sphere.set_field_parameter('bulk_velocity', 
-                                                   sphere.quantities['BulkVelocity'](lazy_reader=False, 
-                                                                                     preload=False))
-                    else:
-                        mylog.error("Invalid parameter: VelocityCenter.")
-                elif self.velocity_center[0] == 'max':
-                    max_grid, max_cell, max_value, max_location = \
-                        self.pf.h.find_max_cell_location(self.velocity_center[1])
-                    sphere.set_field_parameter('bulk_velocity', [max_grid['x-velocity'][max_cell],
-                                                                 max_grid['y-velocity'][max_cell],
-                                                                 max_grid['z-velocity'][max_cell]])
-
             try:
                 profile = BinnedProfile1D(sphere, self.n_profile_bins, "RadiusMpc",
                                                 r_min, halo['r_max'],
-                                                log_space=True, lazy_reader=False,
+                                                log_space=True, lazy_reader=True,
                                                 end_collect=True)
             except EmptyProfileData:
                 mylog.error("Caught EmptyProfileData exception, returning None for this halo.")
@@ -586,9 +604,75 @@
 
         return profile
 
+    def _get_halo_sphere(self, halo):
+        """
+        Returns a sphere object for a given halo, performs the recentering,
+        and calculates bulk velocities.
+        """
+
+        sphere = self.pf.h.sphere(halo['center'], halo['r_max']/self.pf.units['mpc'])
+        if len(sphere._grids) == 0: return None
+        new_sphere = False
+
+        if self.recenter:
+            old = halo['center']
+            if self.recenter in centering_registry:
+                new_x, new_y, new_z = \
+                    centering_registry[self.recenter](sphere)
+            else:
+                # user supplied function
+                new_x, new_y, new_z = self.recenter(sphere)
+            if new_x < self.pf.domain_left_edge[0] or \
+                    new_y < self.pf.domain_left_edge[1] or \
+                    new_z < self.pf.domain_left_edge[2]:
+                mylog.info("Recentering rejected, skipping halo %d" % \
+                    halo['id'])
+                return None
+            halo['center'] = [new_x, new_y, new_z]
+            d = self.pf['kpc'] * periodic_dist(old, halo['center'],
+                self.pf.domain_right_edge - self.pf.domain_left_edge)
+            mylog.info("Recentered halo %d %1.3e kpc away." % (halo['id'], d))
+            # Expand the halo to account for recentering. 
+            halo['r_max'] += d / 1000. # d is in kpc -> want mpc
+            new_sphere = True
+
+        if new_sphere:
+            # Temporary solution to memory leak.
+            for g in self.pf.h.grids:
+                g.clear_data()
+            sphere.clear_data()
+            del sphere
+            sphere = self.pf.h.sphere(halo['center'], halo['r_max']/self.pf.units['mpc'])
+
+        if self._need_bulk_velocity:
+            # Set bulk velocity to zero out radial velocity profiles.
+            if self.velocity_center[0] == 'bulk':
+                if self.velocity_center[1] == 'halo':
+                    sphere.set_field_parameter('bulk_velocity', halo['velocity'])
+                elif self.velocity_center[1] == 'sphere':
+                    mylog.info('Calculating sphere bulk velocity.')
+                    sphere.set_field_parameter('bulk_velocity', 
+                                               sphere.quantities['BulkVelocity'](lazy_reader=True, 
+                                                                                 preload=False))
+                else:
+                    mylog.error("Invalid parameter: velocity_center.")
+                    return None
+            elif self.velocity_center[0] == 'max':
+                mylog.info('Setting bulk velocity with value at max %s.' % self.velocity_center[1])
+                max_val, maxi, mx, my, mz, mg = sphere.quantities['MaxLocation'](self.velocity_center[1],
+                                                                                 lazy_reader=True)
+                max_grid = self.pf.h.grids[mg]
+                max_cell = na.unravel_index(maxi, max_grid.ActiveDimensions)
+                sphere.set_field_parameter('bulk_velocity', [max_grid['x-velocity'][max_cell],
+                                                             max_grid['y-velocity'][max_cell],
+                                                             max_grid['z-velocity'][max_cell]])
+            mylog.info('Bulk velocity set.')
+
+        return sphere
+
     @parallel_blocking_call
     def make_projections(self, axes=[0, 1, 2], halo_list='filtered',
-            save_images=False, save_cube=True):
+                         save_images=False, save_cube=True, njobs=-1):
         r"""Make projections of all halos using specified fields.
         
         After adding fields using `add_projection`, this starts the actual
@@ -608,6 +692,10 @@
         save_cube : bool
             Whether or not to save the HDF5 files of the halo projections.
             Default=True.
+        njobs : int
+            The number of jobs over which to split the projections.  Set
+            to -1 so that each halo is done by a single processor.
+            Default: -1.
         
         Examples
         --------
@@ -656,7 +744,7 @@
                          self.pf.parameters['DomainRightEdge'][w])
                   for w in range(self.pf.parameters['TopGridRank'])]
 
-        for halo in parallel_objects(halo_projection_list, -1):
+        for halo in parallel_objects(halo_projection_list, njobs=njobs):
             if halo is None:
                 continue
             # Check if region will overlap domain edge.
@@ -745,7 +833,7 @@
 
     @parallel_blocking_call
     def analyze_halo_spheres(self, analysis_function, halo_list='filtered',
-                             analysis_output_dir=None):
+                             analysis_output_dir=None, njobs=-1):
         r"""Perform custom analysis on all halos.
         
         This will loop through all halo on the HaloProfiler's list, 
@@ -768,6 +856,10 @@
         analysis_output_dir : string, optional
             If specified, this directory will be created within the dataset to 
             contain any output from the analysis function.  Default: None.
+        njobs : int
+            The number of jobs over which to split the analysis.  Set
+            to -1 so that each halo is done by a single processor.
+            Default: -1.
 
         Examples
         --------
@@ -803,11 +895,11 @@
                 my_output_dir = "%s/%s" % (self.pf.fullpath, analysis_output_dir)
             self.__check_directory(my_output_dir)
 
-        for halo in parallel_objects(halo_analysis_list, -1):
+        for halo in parallel_objects(halo_analysis_list, njobs=njobs):
             if halo is None: continue
 
             # Get a sphere object to analze.
-            sphere = get_halo_sphere(halo, self.pf, recenter=self.recenter)
+            sphere = self._get_halo_sphere(halo)
             if sphere is None: continue
 
             # Call the given analysis function.
@@ -924,6 +1016,9 @@
         lines = f.readlines()
         f.close()
 
+        if not lines:
+            return None
+
         # Get fields from header.
         header = lines.pop(0)
         header = header.strip()
@@ -1042,94 +1137,6 @@
         else:
             os.mkdir(my_output_dir)
 
-def get_halo_sphere(halo, pf, recenter=None):
-    r"""Returns a sphere object for a given halo.
-        
-    With a dictionary containing halo properties, such as center 
-    and r_max, this creates a sphere object and optionally 
-    recenters and recreates the sphere using a recentering function.
-    This is to be used primarily to make spheres for a set of halos 
-    loaded by the HaloProfiler.
-    
-    Parameters
-    ----------
-    halo : dict, required
-        The dictionary containing halo properties used to make the sphere.
-        Required entries:
-            center : list with center coordinates.
-            r_max : sphere radius in Mpc.
-    pf : parameter file object, required
-        The parameter file from which the sphere will be made.
-    recenter : {None, string or function}
-        The exact location of the sphere center can significantly affect 
-        radial profiles.  The halo center loaded by the HaloProfiler will 
-        typically be the dark matter center of mass calculated by a halo 
-        finder.  However, this may not be the best location for centering 
-        profiles of baryon quantities.  For example, one may want to center 
-        on the maximum density.
-        If recenter is given as a string, one of the existing recentering 
-        functions will be used:
-            Min_Dark_Matter_Density : location of minimum dark matter density
-            Max_Dark_Matter_Density : location of maximum dark matter density
-            CoM_Dark_Matter_Density : dark matter center of mass
-            Min_Gas_Density : location of minimum gas density
-            Max_Gas_Density : location of maximum gas density
-            CoM_Gas_Density : gas center of mass
-            Min_Total_Density : location of minimum total density
-            Max_Total_Density : location of maximum total density
-            CoM_Total_Density : total center of mass
-            Min_Temperature : location of minimum temperature
-            Max_Temperature : location of maximum temperature
-        Alternately, a function can be supplied for custom recentering.
-        The function should take only one argument, a sphere object.
-            Example function:
-                def my_center_of_mass(data):
-                   my_x, my_y, my_z = data.quantities['CenterOfMass']()
-                   return (my_x, my_y, my_z)
-
-        Examples: this should primarily be used with the halo list of the HaloProfiler.
-        This is an example with an abstract halo asssuming a pre-defined pf.
-        >>> halo = {'center': [0.5, 0.5, 0.5], 'r_max': 1.0}
-        >>> my_sphere = get_halo_sphere(halo, pf, recenter='Max_Gas_Density')
-        >>> # Assuming the above example function has been defined.
-        >>> my_sphere = get_halo_sphere(halo, pf, recenter=my_center_of_mass)
-    """
-        
-    sphere = pf.h.sphere(halo['center'], halo['r_max']/pf.units['mpc'])
-    if len(sphere._grids) == 0: return None
-    new_sphere = False
-
-    if recenter:
-        old = halo['center']
-        if recenter in centering_registry:
-            new_x, new_y, new_z = \
-                centering_registry[recenter](sphere)
-        else:
-            # user supplied function
-            new_x, new_y, new_z = recenter(sphere)
-        if new_x < pf.domain_left_edge[0] or \
-                new_y < pf.domain_left_edge[1] or \
-                new_z < pf.domain_left_edge[2]:
-            mylog.info("Recentering rejected, skipping halo %d" % \
-                halo['id'])
-            return None
-        halo['center'] = [new_x, new_y, new_z]
-        d = pf['kpc'] * periodic_dist(old, halo['center'],
-            pf.domain_right_edge - pf.domain_left_edge)
-        mylog.info("Recentered halo %d %1.3e kpc away." % (halo['id'], d))
-        # Expand the halo to account for recentering. 
-        halo['r_max'] += d / 1000 # d is in kpc -> want mpc
-        new_sphere = True
-
-    if new_sphere:
-        # Temporary solution to memory leak.
-        for g in pf.h.grids:
-            g.clear_data()
-        sphere.clear_data()
-        del sphere
-        sphere = pf.h.sphere(halo['center'], halo['r_max']/pf.units['mpc'])
-    return sphere
-
 def _shift_projections(pf, projections, oldCenter, newCenter, axis):
     """
     Shift projection data around.


diff -r cd3ad30dcf40fa55519318dc0eb1de63678f0035 -r d33c8b031561083ea6176b026e7c6ae1f420b3f8 yt/convenience.py
--- a/yt/convenience.py
+++ b/yt/convenience.py
@@ -33,6 +33,7 @@
 from yt.config import ytcfg
 from yt.utilities.parameter_file_storage import \
     output_type_registry, \
+    simulation_time_series_registry, \
     EnzoRunDatabase
 
 def load(*args ,**kwargs):
@@ -111,3 +112,14 @@
     f.close()
     return proj
 
+def simulation(parameter_filename, simulation_type):
+    """
+    Loads a simulation time series object of the specified
+    simulation type.
+    """
+
+    if simulation_type not in simulation_time_series_registry:
+        raise YTSimulationNotIdentified(simulation_type)
+
+    return simulation_time_series_registry[simulation_type](parameter_filename)
+


diff -r cd3ad30dcf40fa55519318dc0eb1de63678f0035 -r d33c8b031561083ea6176b026e7c6ae1f420b3f8 yt/data_objects/data_containers.py
--- a/yt/data_objects/data_containers.py
+++ b/yt/data_objects/data_containers.py
@@ -495,7 +495,7 @@
         self._sorted = {}
 
     def get_data(self, fields=None, in_grids=False):
-        if self._grids == None:
+        if self._grids is None:
             self._get_list_of_grids()
         points = []
         if not fields:
@@ -2543,7 +2543,18 @@
     def cut_region(self, field_cuts):
         """
         Return an InLineExtractedRegion, where the grid cells are cut on the
-        fly with a set of field_cuts.
+        fly with a set of field_cuts.  It is very useful for applying 
+        conditions to the fields in your data object.
+        
+        Examples
+        --------
+        To find the total mass of gas above 10^6 K in your volume:
+
+        >>> pf = load("RedshiftOutput0005")
+        >>> ad = pf.h.all_data()
+        >>> cr = ad.cut_region(["grid['Temperature'] > 1e6"])
+        >>> print cr.quantities["TotalQuantity"]("CellMassMsun")
+
         """
         return InLineExtractedRegionBase(self, field_cuts)
 
@@ -3292,6 +3303,40 @@
         pointI = na.where(k == True)
         return pointI
 
+class AMRMaxLevelCollection(AMR3DData):
+    _type_name = "grid_collection_max_level"
+    _con_args = ("center", "max_level")
+    def __init__(self, center, max_level, fields = None,
+                 pf = None, **kwargs):
+        """
+        By selecting an arbitrary *max_level*, we can act on those grids.
+        Child cells are masked when the level of the grid is below the max
+        level.
+        """
+        AMR3DData.__init__(self, center, fields, pf, **kwargs)
+        self.max_level = max_level
+        self._refresh_data()
+
+    def _get_list_of_grids(self):
+        if self._grids is not None: return
+        gi = (self.pf.h.grid_levels <= self.max_level)[:,0]
+        self._grids = self.pf.h.grids[gi]
+
+    def _is_fully_enclosed(self, grid):
+        return True
+
+    @cache_mask
+    def _get_cut_mask(self, grid):
+        return na.ones(grid.ActiveDimensions, dtype='bool')
+
+    def _get_point_indices(self, grid, use_child_mask=True):
+        k = na.ones(grid.ActiveDimensions, dtype='bool')
+        if use_child_mask and grid.Level < self.max_level:
+            k[grid.child_indices] = False
+        pointI = na.where(k == True)
+        return pointI
+
+
 class AMRSphereBase(AMR3DData):
     """
     A sphere of points
@@ -3369,8 +3414,6 @@
             The left edge of the region to be extracted
         dims : array_like
             Number of cells along each axis of resulting covering_grid
-        right_edge : array_like, optional
-            The right edge of the region to be extracted
         fields : array_like, optional
             A list of fields that you'd like pre-generated for your object
 
@@ -3529,16 +3572,13 @@
         left_edge : array_like
             The left edge of the region to be extracted
         dims : array_like
-            Number of cells along each axis of resulting covering_grid
-        right_edge : array_like, optional
-            The right edge of the region to be extracted
+            Number of cells along each axis of resulting covering_grid.
         fields : array_like, optional
             A list of fields that you'd like pre-generated for your object
 
         Example
         -------
         cube = pf.h.smoothed_covering_grid(2, left_edge=[0.0, 0.0, 0.0], \
-                                  right_edge=[1.0, 1.0, 1.0],
                                   dims=[128, 128, 128])
         """
         self._base_dx = (
@@ -3577,10 +3617,16 @@
         for gi, grid in enumerate(self._grids):
             if self._use_pbar: pbar.update(gi)
             if grid.Level > last_level and grid.Level <= self.level:
+                mylog.debug("Updating level state to %s", last_level + 1)
                 self._update_level_state(last_level + 1)
                 self._refine(1, fields_to_get)
                 last_level = grid.Level
             self._get_data_from_grid(grid, fields_to_get)
+        while last_level < self.level:
+            mylog.debug("Grid-free refinement %s to %s", last_level, last_level + 1)
+            self._update_level_state(last_level + 1)
+            self._refine(1, fields_to_get)
+            last_level += 1
         if self.level > 0:
             for field in fields_to_get:
                 self[field] = self[field][1:-1,1:-1,1:-1]


diff -r cd3ad30dcf40fa55519318dc0eb1de63678f0035 -r d33c8b031561083ea6176b026e7c6ae1f420b3f8 yt/data_objects/hierarchy.py
--- a/yt/data_objects/hierarchy.py
+++ b/yt/data_objects/hierarchy.py
@@ -381,18 +381,18 @@
         """
         Prints out (stdout) relevant information about the simulation
         """
-        header = "%3s\t%6s\t%11s" % ("level","# grids", "# cells")
+        header = "%3s\t%6s\t%14s" % ("level","# grids", "# cells")
         print header
         print "%s" % (len(header.expandtabs())*"-")
         for level in xrange(MAXLEVEL):
             if (self.level_stats['numgrids'][level]) == 0:
                 break
-            print "% 3i\t% 6i\t% 11i" % \
+            print "% 3i\t% 6i\t% 14i" % \
                   (level, self.level_stats['numgrids'][level],
                    self.level_stats['numcells'][level])
             dx = self.select_grids(level)[0].dds[0]
         print "-" * 28
-        print "   \t% 6i\t% 11i" % (self.level_stats['numgrids'].sum(), self.level_stats['numcells'].sum())
+        print "   \t% 6i\t% 14i" % (self.level_stats['numgrids'].sum(), self.level_stats['numcells'].sum())
         print "\n"
         try:
             print "z = %0.8f" % (self["CosmologyCurrentRedshift"])


diff -r cd3ad30dcf40fa55519318dc0eb1de63678f0035 -r d33c8b031561083ea6176b026e7c6ae1f420b3f8 yt/data_objects/time_series.py
--- a/yt/data_objects/time_series.py
+++ b/yt/data_objects/time_series.py
@@ -33,7 +33,9 @@
 from .derived_quantities import quantity_info
 from yt.utilities.exceptions import YTException
 from yt.utilities.parallel_tools.parallel_analysis_interface \
-    import parallel_objects
+    import parallel_objects, parallel_root_only
+from yt.utilities.parameter_file_storage import \
+    simulation_time_series_registry
 
 class AnalysisTaskProxy(object):
     def __init__(self, time_series):
@@ -189,3 +191,67 @@
         # hierarchy
         cls = getattr(pf.h, self.data_object_name)
         return cls(*self._args, **self._kwargs)
+
+
+class SimulationTimeSeries(TimeSeriesData):
+    class __metaclass__(type):
+        def __init__(cls, name, b, d):
+            type.__init__(cls, name, b, d)
+            code_name = name[:name.find('Simulation')]
+            if code_name:
+                simulation_time_series_registry[code_name] = cls
+                mylog.debug("Registering simulation: %s as %s", code_name, cls)
+
+    def __init__(self, parameter_filename):
+        """
+        Base class for generating simulation time series types.
+        Principally consists of a *parameter_filename*.
+        """
+
+        if not os.path.exists(parameter_filename):
+            raise IOError(parameter_filename)
+        self.parameter_filename = parameter_filename
+        self.basename = os.path.basename(parameter_filename)
+        self.directory = os.path.dirname(parameter_filename)
+        self.parameters = {}
+
+        # Set some parameter defaults.
+        self._set_parameter_defaults()
+        # Read the simulation parameter file.
+        self._parse_parameter_file()
+        # Set up time units dictionary.
+        self._set_time_units()
+
+        # Figure out the starting and stopping times and redshift.
+        self._calculate_simulation_bounds()
+        self.print_key_parameters()
+        
+        # Get all possible datasets.
+        self._get_all_outputs()
+
+    def __repr__(self):
+        return self.parameter_filename
+
+    @parallel_root_only
+    def print_key_parameters(self):
+        """
+        Print out some key parameters for the simulation.
+        """
+        for a in ["domain_dimensions", "domain_left_edge",
+                  "domain_right_edge", "initial_time", "final_time",
+                  "stop_cycle", "cosmological_simulation"]:
+            if not hasattr(self, a):
+                mylog.error("Missing %s in parameter file definition!", a)
+                continue
+            v = getattr(self, a)
+            mylog.info("Parameters: %-25s = %s", a, v)
+        if hasattr(self, "cosmological_simulation") and \
+           getattr(self, "cosmological_simulation"):
+            for a in ["omega_lambda", "omega_matter",
+                      "hubble_constant", "initial_redshift",
+                      "final_redshift"]:
+                if not hasattr(self, a):
+                    mylog.error("Missing %s in parameter file definition!", a)
+                    continue
+                v = getattr(self, a)
+                mylog.info("Parameters: %-25s = %s", a, v)


diff -r cd3ad30dcf40fa55519318dc0eb1de63678f0035 -r d33c8b031561083ea6176b026e7c6ae1f420b3f8 yt/frontends/enzo/api.py
--- a/yt/frontends/enzo/api.py
+++ b/yt/frontends/enzo/api.py
@@ -38,6 +38,9 @@
       EnzoStaticOutput, \
       EnzoStaticOutputInMemory
 
+from .simulation_handling import \
+    EnzoSimulation
+
 from .fields import \
       EnzoFieldInfo, \
       Enzo2DFieldInfo, \


diff -r cd3ad30dcf40fa55519318dc0eb1de63678f0035 -r d33c8b031561083ea6176b026e7c6ae1f420b3f8 yt/frontends/enzo/io.py
--- a/yt/frontends/enzo/io.py
+++ b/yt/frontends/enzo/io.py
@@ -201,6 +201,8 @@
     _data_style = "enzo_packed_3d_gz"
 
     def modify(self, field):
+        if len(field.shape) < 3:
+            return field
         tr = field[3:-3,3:-3,3:-3].swapaxes(0,2)
         return tr.copy() # To ensure contiguous
 


diff -r cd3ad30dcf40fa55519318dc0eb1de63678f0035 -r d33c8b031561083ea6176b026e7c6ae1f420b3f8 yt/frontends/enzo/simulation_handling.py
--- /dev/null
+++ b/yt/frontends/enzo/simulation_handling.py
@@ -0,0 +1,633 @@
+"""
+EnzoSimulation class and member functions.
+
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: Michigan State University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2008-2012 Britton Smith.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+"""
+
+from yt.funcs import *
+
+import numpy as na
+import glob
+import os
+
+from yt.data_objects.time_series import \
+    SimulationTimeSeries, TimeSeriesData
+from yt.utilities.cosmology import \
+    Cosmology, \
+    EnzoCosmology
+from yt.utilities.exceptions import \
+    AmbiguousOutputs, \
+    MissingParameter, \
+    NoStoppingCondition
+
+from yt.convenience import \
+    load
+
+class EnzoSimulation(SimulationTimeSeries):
+    r"""Class for creating TimeSeriesData object from an Enzo
+    simulation parameter file.
+    """
+    def __init__(self, parameter_filename):
+        r"""Initialize an Enzo Simulation object.
+
+        Upon creation, the parameter file is parsed and the time and redshift
+        are calculated and stored in all_outputs.  A time units dictionary is
+        instantiated to allow for time outputs to be requested with physical
+        time units.  The get_time_series can be used to generate a
+        TimeSeriesData object.
+
+        parameter_filename : str
+            The simulation parameter file.
+        
+        Examples
+        --------
+        >>> from yt.mods import *
+        >>> es = ES.EnzoSimulation("my_simulation.par")
+        >>> print es.all_outputs
+
+        """
+        SimulationTimeSeries.__init__(self, parameter_filename)
+        
+    def get_time_series(self, time_data=True, redshift_data=True,
+                        initial_time=None, final_time=None, time_units='1',
+                        initial_redshift=None, final_redshift=None,
+                        initial_cycle=None, final_cycle=None,
+                        times=None, redshifts=None, tolerance=None,
+                        find_outputs=False, parallel=True):
+
+        """
+        Instantiate a TimeSeriesData object for a set of outputs.
+
+        If no additional keywords given, a TimeSeriesData object will be
+        created with all potential datasets created by the simulation.
+
+        Outputs can be gather by specifying a time or redshift range
+        (or combination of time and redshift), with a specific list of
+        times or redshifts, a range of cycle numbers (for cycle based
+        output), or by simply searching all subdirectories within the
+        simulation directory.
+
+        time_data : bool
+            Whether or not to include time outputs when gathering
+            datasets for time series.
+            Default: True.
+        redshift_data : bool
+            Whether or not to include redshift outputs when gathering
+            datasets for time series.
+            Default: True.
+        initial_time : float
+            The earliest time for outputs to be included.  If None,
+            the initial time of the simulation is used.  This can be
+            used in combination with either final_time or
+            final_redshift.
+            Default: None.
+        final_time : float
+            The latest time for outputs to be included.  If None,
+            the final time of the simulation is used.  This can be
+            used in combination with either initial_time or
+            initial_redshift.
+            Default: None.
+        times : array_like
+            A list of times for which outputs will be found.
+            Default: None.
+        time_units : str
+            The time units used for requesting outputs by time.
+            Default: '1' (code units).
+        initial_redshift : float
+            The earliest redshift for outputs to be included.  If None,
+            the initial redshift of the simulation is used.  This can be
+            used in combination with either final_time or
+            final_redshift.
+            Default: None.
+        final_time : float
+            The latest redshift for outputs to be included.  If None,
+            the final redshift of the simulation is used.  This can be
+            used in combination with either initial_time or
+            initial_redshift.
+            Default: None.
+        redshifts : array_like
+            A list of redshifts for which outputs will be found.
+            Default: None.
+        initial_cycle : float
+            The earliest cycle for outputs to be included.  If None,
+            the initial cycle of the simulation is used.  This can
+            only be used with final_cycle.
+            Default: None.
+        final_cycle : float
+            The latest cycle for outputs to be included.  If None,
+            the final cycle of the simulation is used.  This can
+            only be used in combination with initial_cycle.
+            Default: None.
+        tolerance : float
+            Used in combination with "times" or "redshifts" keywords,
+            this is the tolerance within which outputs are accepted
+            given the requested times or redshifts.  If None, the
+            nearest output is always taken.
+            Default: None.
+        find_outputs : bool
+            If True, subdirectories within the GlobalDir directory are
+            searched one by one for datasets.  Time and redshift
+            information are gathered by temporarily instantiating each
+            dataset.  This can be used when simulation data was created
+            in a non-standard way, making it difficult to guess the
+            corresponding time and redshift information.
+            Default: False.
+        parallel : bool/int
+            If True, the generated TimeSeriesData will divide the work
+            such that a single processor works on each dataset.  If an
+            integer is supplied, the work will be divided into that
+            number of jobs.
+            Default: True.
+
+        Examples
+        --------
+        >>> es.get_time_series(initial_redshift=10, final_time=13.7,
+                               time_units='Gyr', redshift_data=False)
+
+        >>> es.get_time_series(redshifts=[3, 2, 1, 0])
+
+        >>> es.get_time_series(final_cycle=100000)
+
+        >>> es.get_time_series(find_outputs=True)
+
+        >>> # after calling get_time_series
+        >>> for pf in es.piter():
+        >>>     pc = PlotCollection(pf, 'c')
+        >>>     pc.add_projection('Density', 0)
+        >>>     pc.save()
+
+        """
+
+        if (initial_redshift is not None or \
+            final_redshift is not None) and \
+            not self.cosmological_simulation:
+            mylog.error('An initial or final redshift has been given for a noncosmological simulation.')
+            return
+
+        if find_outputs:
+            my_outputs = self._find_outputs()
+
+        else:
+            if time_data and redshift_data:
+                my_all_outputs = self.all_outputs
+            elif time_data:
+                my_all_outputs = self.all_time_outputs
+            elif redshift_data:
+                my_all_outputs = self.all_redshift_outputs
+            else:
+                mylog.error('Both time_data and redshift_data are False.')
+                return
+
+            if times is not None:
+                my_outputs = self._get_outputs_by_time(times, tolerance=tolerance,
+                                                       outputs=my_all_outputs,
+                                                       time_units=time_units)
+
+            elif redshifts is not None:
+                my_outputs = self._get_outputs_by_redshift(redshifts, tolerance=tolerance,
+                                                           outputs=my_all_outputs)
+
+            elif initial_cycle is not None or final_cycle is not None:
+                if initial_cycle is None:
+                    initial_cycle = 0
+                else:
+                    initial_cycle = max(initial_cycle, 0)
+                if final_cycle is None:
+                    final_cycle = self.parameters['StopCycle']
+                else:
+                    final_cycle = min(final_cycle, self.parameters['StopCycle'])
+                my_outputs = my_all_outputs[int(ceil(float(initial_cycle) /
+                                                     self.parameters['CycleSkipDataDump'])):
+                                            (final_cycle /  self.parameters['CycleSkipDataDump'])+1]
+
+            else:
+                if initial_time is not None:
+                    my_initial_time = initial_time / self.time_units[time_units]
+                elif initial_redshift is not None:
+                    my_initial_time = self.enzo_cosmology.ComputeTimeFromRedshift(initial_redshift) / \
+                        self.enzo_cosmology.TimeUnits
+                else:
+                    my_initial_time = self.initial_time
+
+                if final_time is not None:
+                    my_final_time = final_time / self.time_units[time_units]
+                elif final_redshift is not None:
+                    my_final_time = self.enzo_cosmology.ComputeTimeFromRedshift(final_redshift) / \
+                        self.enzo_cosmology.TimeUnits
+                else:
+                    my_final_time = self.final_time
+                    
+                my_times = na.array(map(lambda a:a['time'], my_all_outputs))
+                my_indices = na.digitize([my_initial_time, my_final_time], my_times)
+                if my_initial_time == my_times[my_indices[0] - 1]: my_indices[0] -= 1
+                my_outputs = my_all_outputs[my_indices[0]:my_indices[1]]
+
+        TimeSeriesData.__init__(self, outputs=[output['filename'] for output in my_outputs],
+                                parallel=parallel)
+        mylog.info("%d outputs loaded into time series." % len(my_outputs))
+
+    def _parse_parameter_file(self):
+        """
+        Parses the parameter file and establishes the various
+        dictionaries.
+        """
+
+        self.conversion_factors = {}
+        redshift_outputs = []
+
+        # Let's read the file
+        lines = open(self.parameter_filename).readlines()
+        for line in (l.strip() for l in lines):
+            if '#' in line: line = line[0:line.find('#')]
+            if '//' in line: line = line[0:line.find('//')]
+            if len(line) < 2: continue
+            param, vals = (i.strip() for i in line.split("="))
+            # First we try to decipher what type of value it is.
+            vals = vals.split()
+            # Special case approaching.
+            if "(do" in vals: vals = vals[:1]
+            if len(vals) == 0:
+                pcast = str # Assume NULL output
+            else:
+                v = vals[0]
+                # Figure out if it's castable to floating point:
+                try:
+                    float(v)
+                except ValueError:
+                    pcast = str
+                else:
+                    if any("." in v or "e+" in v or "e-" in v for v in vals):
+                        pcast = float
+                    elif v == "inf":
+                        pcast = str
+                    else:
+                        pcast = int
+            # Now we figure out what to do with it.
+            if param.endswith("Units") and not param.startswith("Temperature"):
+                dataType = param[:-5]
+                # This one better be a float.
+                self.conversion_factors[dataType] = float(vals[0])
+            if param.startswith("CosmologyOutputRedshift["):
+                index = param[param.find("[")+1:param.find("]")]
+                redshift_outputs.append({'index':int(index), 'redshift':float(vals[0])})
+            elif len(vals) == 0:
+                vals = ""
+            elif len(vals) == 1:
+                vals = pcast(vals[0])
+            else:
+                vals = na.array([pcast(i) for i in vals if i != "-99999"])
+            self.parameters[param] = vals
+        self.refine_by = self.parameters["RefineBy"]
+        self.dimensionality = self.parameters["TopGridRank"]
+        if self.dimensionality > 1:
+            self.domain_dimensions = self.parameters["TopGridDimensions"]
+            if len(self.domain_dimensions) < 3:
+                tmp = self.domain_dimensions.tolist()
+                tmp.append(1)
+                self.domain_dimensions = na.array(tmp)
+            self.domain_left_edge = na.array(self.parameters["DomainLeftEdge"],
+                                             "float64").copy()
+            self.domain_right_edge = na.array(self.parameters["DomainRightEdge"],
+                                             "float64").copy()
+        else:
+            self.domain_left_edge = na.array(self.parameters["DomainLeftEdge"],
+                                             "float64")
+            self.domain_right_edge = na.array(self.parameters["DomainRightEdge"],
+                                             "float64")
+            self.domain_dimensions = na.array([self.parameters["TopGridDimensions"],1,1])
+
+        if self.parameters["ComovingCoordinates"]:
+            cosmo_attr = {'omega_lambda': 'CosmologyOmegaLambdaNow',
+                          'omega_matter': 'CosmologyOmegaMatterNow',
+                          'hubble_constant': 'CosmologyHubbleConstantNow',
+                          'initial_redshift': 'CosmologyInitialRedshift',
+                          'final_redshift': 'CosmologyFinalRedshift'}
+            self.cosmological_simulation = 1
+            for a, v in cosmo_attr.items():
+                if not v in self.parameters:
+                    raise MissingParameter(self.parameter_filename, v)
+                setattr(self, a, self.parameters[v])
+        else:
+            self.omega_lambda = self.omega_matter = \
+                self.hubble_constant = self.cosmological_simulation = 0.0
+
+        # make list of redshift outputs
+        self.all_redshift_outputs = []
+        if not self.cosmological_simulation: return
+        for output in redshift_outputs:
+            output['filename'] = os.path.join(self.parameters['GlobalDir'],
+                                              "%s%04d" % (self.parameters['RedshiftDumpDir'],
+                                                          output['index']),
+                                              "%s%04d" % (self.parameters['RedshiftDumpName'],
+                                                          output['index']))
+            del output['index']
+        self.all_redshift_outputs = redshift_outputs
+
+    def _calculate_redshift_dump_times(self):
+        "Calculates time from redshift of redshift outputs."
+
+        if not self.cosmological_simulation: return
+        for output in self.all_redshift_outputs:
+            output['time'] = self.enzo_cosmology.ComputeTimeFromRedshift(output['redshift']) / \
+                self.enzo_cosmology.TimeUnits
+
+    def _calculate_time_outputs(self):
+        "Calculate time outputs and their redshifts if cosmological."
+
+        if self.final_time is None or \
+            not 'dtDataDump' in self.parameters or \
+            self.parameters['dtDataDump'] <= 0.0: return []
+
+        self.all_time_outputs = []
+        index = 0
+        current_time = self.initial_time
+        while current_time <= self.final_time + self.parameters['dtDataDump']:
+            filename = os.path.join(self.parameters['GlobalDir'],
+                                    "%s%04d" % (self.parameters['DataDumpDir'], index),
+                                    "%s%04d" % (self.parameters['DataDumpName'], index))
+
+            output = {'index': index, 'filename': filename, 'time': current_time}
+            output['time'] = min(output['time'], self.final_time)
+            if self.cosmological_simulation:
+                output['redshift'] = self.enzo_cosmology.ComputeRedshiftFromTime(
+                    current_time * self.enzo_cosmology.TimeUnits)
+
+            self.all_time_outputs.append(output)
+            if na.abs(self.final_time - current_time) / self.final_time < 1e-4: break
+            current_time += self.parameters['dtDataDump']
+            index += 1
+
+    def _calculate_cycle_outputs(self):
+        "Calculate cycle outputs."
+
+        mylog.warn('Calculating cycle outputs.  Dataset times will be unavailable.')
+
+        if self.stop_cycle is None or \
+            not 'CycleSkipDataDump' in self.parameters or \
+            self.parameters['CycleSkipDataDump'] <= 0.0: return []
+
+        self.all_time_outputs = []
+        index = 0
+        for cycle in range(0, self.stop_cycle+1, self.parameters['CycleSkipDataDump']):
+            filename = os.path.join(self.parameters['GlobalDir'],
+                                    "%s%04d" % (self.parameters['DataDumpDir'], index),
+                                    "%s%04d" % (self.parameters['DataDumpName'], index))
+
+            output = {'index': index, 'filename': filename, 'cycle': cycle}
+            self.all_time_outputs.append(output)
+            index += 1
+
+    def _get_all_outputs(self):
+        "Get all potential datasets and combine into a time-sorted list."
+
+        if self.parameters['dtDataDump'] > 0 and \
+            self.parameters['CycleSkipDataDump'] > 0:
+            mylog.info("Simulation %s has both dtDataDump and CycleSkipDataDump set." % self.parameter_filename )
+            mylog.info("    Unable to calculate datasets.  Attempting to search in the current directory")
+            self.all_time_outputs = self._find_outputs()
+
+        # Get all time or cycle outputs.
+        elif self.parameters['CycleSkipDataDump'] > 0:
+            self._calculate_cycle_outputs()
+        else:
+            self._calculate_time_outputs()
+
+        # Calculate times for redshift outputs.
+        self._calculate_redshift_dump_times()
+
+        self.all_outputs = self.all_time_outputs + self.all_redshift_outputs
+        if self.parameters['CycleSkipDataDump'] <= 0:
+            self.all_outputs.sort(key=lambda obj:obj['time'])
+
+        mylog.info("Total datasets: %d." % len(self.all_outputs))
+
+    def _calculate_simulation_bounds(self):
+        """
+        Figure out the starting and stopping time and redshift for the simulation.
+        """
+
+        if 'StopCycle' in self.parameters:
+            self.stop_cycle = self.parameters['StopCycle']
+
+        # Convert initial/final redshifts to times.
+        if self.cosmological_simulation:
+            # Instantiate EnzoCosmology object for units and time conversions.
+            self.enzo_cosmology = EnzoCosmology(HubbleConstantNow=
+                                                (100.0 * self.parameters['CosmologyHubbleConstantNow']),
+                                                OmegaMatterNow=self.parameters['CosmologyOmegaMatterNow'],
+                                                OmegaLambdaNow=self.parameters['CosmologyOmegaLambdaNow'],
+                                                InitialRedshift=self.parameters['CosmologyInitialRedshift'])
+            self.initial_time = self.enzo_cosmology.ComputeTimeFromRedshift(self.initial_redshift) / \
+                self.enzo_cosmology.TimeUnits
+            self.final_time = self.enzo_cosmology.ComputeTimeFromRedshift(self.final_redshift) / \
+                self.enzo_cosmology.TimeUnits
+
+        # If not a cosmology simulation, figure out the stopping criteria.
+        else:
+            if 'InitialTime' in self.parameters:
+                self.initial_time = self.parameters['InitialTime']
+            else:
+                self.initial_time = 0.
+
+            if 'StopTime' in self.parameters:
+                self.final_time = self.parameters['StopTime']
+            else:
+                self.final_time = None
+            if not ('StopTime' in self.parameters or
+                    'StopCycle' in self.parameters):
+                raise NoStoppingCondition(self.parameter_filename)
+            if self.final_time is None:
+                mylog.warn('Simulation %s has no stop time set, stopping condition will be based only on cycles.' %
+                           self.parameter_filename)
+
+    def _set_parameter_defaults(self):
+        "Set some default parameters to avoid problems if they are not in the parameter file."
+
+        self.parameters['GlobalDir'] = self.directory
+        self.parameters['DataDumpName'] = "data"
+        self.parameters['DataDumpDir'] = "DD"
+        self.parameters['RedshiftDumpName'] = "RedshiftOutput"
+        self.parameters['RedshiftDumpDir'] = "RD"
+        self.parameters['ComovingCoordinates'] = 0
+        self.parameters['TopGridRank'] = 3
+        self.parameters['DomainLeftEdge'] = na.zeros(self.parameters['TopGridRank'])
+        self.parameters['DomainRightEdge'] = na.ones(self.parameters['TopGridRank'])
+        self.parameters['Refineby'] = 2 # technically not the enzo default
+        self.parameters['StopCycle'] = 100000
+        self.parameters['dtDataDump'] = 0.
+        self.parameters['CycleSkipDataDump'] = 0.
+        self.parameters['TimeUnits'] = 1.
+
+    def _set_time_units(self):
+        """
+        Set up a dictionary of time units conversions.
+        """
+
+        self.time_units = {}
+        if self.cosmological_simulation:
+            self.parameters['TimeUnits'] = 2.52e17 / na.sqrt(self.omega_matter) \
+                / self.hubble_constant / (1 + self.initial_redshift)**1.5
+        self.time_units['1'] = 1.
+        self.time_units['seconds'] = self.parameters['TimeUnits']
+        self.time_units['years'] = self.time_units['seconds'] / (365*3600*24.0)
+        self.time_units['days']  = self.time_units['seconds'] / (3600*24.0)
+        self.time_units['Myr'] = self.time_units['years'] / 1.0e6
+        self.time_units['Gyr']  = self.time_units['years'] / 1.0e9
+
+    def _find_outputs(self):
+        """
+        Search for directories matching the data dump keywords.
+        If found, get dataset times py opening the pf.
+        """
+
+        # look for time outputs.
+        potential_outputs = glob.glob(os.path.join(self.parameters['GlobalDir'],
+                                                   "%s*" % self.parameters['DataDumpDir'])) + \
+                            glob.glob(os.path.join(self.parameters['GlobalDir'],
+                                                   "%s*" % self.parameters['RedshiftDumpDir']))
+        time_outputs = []
+        mylog.info("Checking %d potential time outputs." % 
+                   len(potential_outputs))
+
+        for output in potential_outputs:
+            if self.parameters['DataDumpDir'] in output:
+                dir_key = self.parameters['DataDumpDir']
+                output_key = self.parameters['DataDumpName']
+            else:
+                dir_key = self.parameters['RedshiftDumpDir']
+                output_key = self.parameters['RedshiftDumpName']
+            index = output[output.find(dir_key) + len(dir_key):]
+            filename = os.path.join(self.parameters['GlobalDir'],
+                                    "%s%s" % (dir_key, index),
+                                    "%s%s" % (output_key, index))
+            if os.path.exists(filename):
+                try:
+                    pf = load(filename)
+                    if pf is not None:
+                        time_outputs.append({'filename': filename, 'time': pf.current_time})
+                        if pf.cosmological_simulation:
+                            time_outputs[-1]['redshift'] = pf.current_redshift
+                except YTOutputNotIdentified:
+                    mylog.error('Failed to load %s' % filename)
+
+        mylog.info("Located %d time outputs." % len(time_outputs))
+        time_outputs.sort(key=lambda obj: obj['time'])
+        return time_outputs
+
+    def _get_outputs_by_key(self, key, values, tolerance=None, outputs=None):
+        r"""Get datasets at or near to given values.
+        
+        Parameters
+        ----------
+        key: str
+            The key by which to retrieve outputs, usually 'time' or
+            'redshift'.
+        values: array_like
+            A list of values, given as floats.
+        tolerance : float
+            If not None, do not return a dataset unless the value is
+            within the tolerance value.  If None, simply return the
+            nearest dataset.
+            Default: None.
+        outputs : list
+            The list of outputs from which to choose.  If None,
+            self.all_outputs is used.
+            Default: None.
+        
+        Examples
+        --------
+        >>> datasets = es.get_outputs_by_key('redshift', [0, 1, 2], tolerance=0.1)
+        
+        """
+
+        values = ensure_list(values)
+        if outputs is None:
+            outputs = self.all_outputs
+        my_outputs = []
+        for value in values:
+            outputs.sort(key=lambda obj:na.fabs(value - obj[key]))
+            if (tolerance is None or na.abs(value - outputs[0][key]) <= tolerance) \
+                    and outputs[0] not in my_outputs:
+                my_outputs.append(outputs[0])
+            else:
+                mylog.error("No dataset added for %s = %f." % (key, value))
+
+        outputs.sort(key=lambda obj: obj['time'])
+        return my_outputs
+
+    def _get_outputs_by_redshift(self, redshifts, tolerance=None, outputs=None):
+        r"""Get datasets at or near to given redshifts.
+        
+        Parameters
+        ----------
+        redshifts: array_like
+            A list of redshifts, given as floats.
+        tolerance : float
+            If not None, do not return a dataset unless the value is
+            within the tolerance value.  If None, simply return the
+            nearest dataset.
+            Default: None.
+        outputs : list
+            The list of outputs from which to choose.  If None,
+            self.all_outputs is used.
+            Default: None.
+        
+        Examples
+        --------
+        >>> datasets = es.get_outputs_by_redshift([0, 1, 2], tolerance=0.1)
+        
+        """
+
+        return self._get_outputs_by_key('redshift', redshifts, tolerance=tolerance,
+                                     outputs=outputs)
+
+    def _get_outputs_by_time(self, times, tolerance=None, outputs=None,
+                             time_units='1'):
+        r"""Get datasets at or near to given times.
+        
+        Parameters
+        ----------
+        times: array_like
+            A list of times, given in code units as floats.
+        tolerance : float
+            If not None, do not return a dataset unless the time is
+            within the tolerance value.  If None, simply return the
+            nearest dataset.
+            Default = None.
+        outputs : list
+            The list of outputs from which to choose.  If None,
+            self.all_outputs is used.
+            Default: None.
+        time_units : str
+            The units of the list of times.
+            Default: '1' (code units).
+        
+        Examples
+        --------
+        >>> datasets = es.get_outputs_by_time([600, 500, 400], tolerance=10.)
+        
+        """
+
+        times = na.array(times) / self.time_units[time_units]
+        return self._get_outputs_by_key('time', times, tolerance=tolerance,
+                                        outputs=outputs)
+


diff -r cd3ad30dcf40fa55519318dc0eb1de63678f0035 -r d33c8b031561083ea6176b026e7c6ae1f420b3f8 yt/mods.py
--- a/yt/mods.py
+++ b/yt/mods.py
@@ -67,7 +67,8 @@
     add_quantity, quantity_info
 
 from yt.frontends.enzo.api import \
-    EnzoStaticOutput, EnzoStaticOutputInMemory, EnzoFieldInfo, \
+    EnzoStaticOutput, EnzoStaticOutputInMemory, \
+    EnzoSimulation, EnzoFieldInfo, \
     add_enzo_field, add_enzo_1d_field, add_enzo_2d_field
 
 from yt.frontends.castro.api import \
@@ -128,7 +129,8 @@
 for name, cls in callback_registry.items():
     exec("%s = cls" % name)
 
-from yt.convenience import load, projload
+from yt.convenience import \
+    load, projload, simulation
 
 # Import some helpful math utilities
 from yt.utilities.math_utils import \


diff -r cd3ad30dcf40fa55519318dc0eb1de63678f0035 -r d33c8b031561083ea6176b026e7c6ae1f420b3f8 yt/utilities/exceptions.py
--- a/yt/utilities/exceptions.py
+++ b/yt/utilities/exceptions.py
@@ -67,3 +67,37 @@
         if self.obj_type == "slice":
             s += "  It may lie on a grid face.  Try offsetting slightly."
         return s
+
+class YTSimulationNotIdentified(YTException):
+    def __init__(self, sim_type):
+        YTException.__init__(self)
+        self.sim_type = sim_type
+
+    def __str__(self):
+        return "Simulation time-series type %s not defined." % self.sim_type
+
+class AmbiguousOutputs(YTException):
+    def __init__(self, pf):
+        YTException.__init__(self, pf)
+
+    def __str__(self):
+        return "Simulation %s has both dtDataDump and CycleSkipDataDump set.  Unable to calculate datasets." % \
+            self.pf
+
+class MissingParameter(YTException):
+    def __init__(self, pf, parameter):
+        YTException.__init__(self, pf)
+        self.parameter = parameter
+
+    def __str__(self):
+        return "Parameter file %s is missing %s parameter." % \
+            (self.pf, self.parameter)
+
+class NoStoppingCondition(YTException):
+    def __init__(self, pf):
+        YTException.__init__(self, pf)
+
+    def __str__(self):
+        return "Simulation %s has no stopping condition.  StopTime or StopCycle should be set." % \
+            self.pf
+


diff -r cd3ad30dcf40fa55519318dc0eb1de63678f0035 -r d33c8b031561083ea6176b026e7c6ae1f420b3f8 yt/utilities/parallel_tools/parallel_analysis_interface.py
--- a/yt/utilities/parallel_tools/parallel_analysis_interface.py
+++ b/yt/utilities/parallel_tools/parallel_analysis_interface.py
@@ -343,7 +343,6 @@
 def parallel_objects(objects, njobs = 0, storage = None, barrier = True):
     if not parallel_capable:
         njobs = 1
-        mylog.warn("parallel_objects() is being used when parallel_capable is false. The loop is not being run in parallel. This may not be what was expected.")
     my_communicator = communication_system.communicators[-1]
     my_size = my_communicator.size
     if njobs <= 0:


diff -r cd3ad30dcf40fa55519318dc0eb1de63678f0035 -r d33c8b031561083ea6176b026e7c6ae1f420b3f8 yt/utilities/parameter_file_storage.py
--- a/yt/utilities/parameter_file_storage.py
+++ b/yt/utilities/parameter_file_storage.py
@@ -33,6 +33,7 @@
     parallel_simple_proxy
 
 output_type_registry = {}
+simulation_time_series_registry = {}
 _field_names = ('hash', 'bn', 'fp', 'tt', 'ctid', 'class_name', 'last_seen')
 
 class NoParameterShelf(Exception):


diff -r cd3ad30dcf40fa55519318dc0eb1de63678f0035 -r d33c8b031561083ea6176b026e7c6ae1f420b3f8 yt/visualization/volume_rendering/camera.py
--- a/yt/visualization/volume_rendering/camera.py
+++ b/yt/visualization/volume_rendering/camera.py
@@ -214,8 +214,8 @@
                                      unit_vectors[1]*width[1],
                                      unit_vectors[2]*width[2]])
         self.origin = center - 0.5*na.dot(width,unit_vectors)
-        self.back_center =  center - 0.5*width[0]*unit_vectors[2]
-        self.front_center = center + 0.5*width[0]*unit_vectors[2]         
+        self.back_center =  center - 0.5*width[2]*unit_vectors[2]
+        self.front_center = center + 0.5*width[2]*unit_vectors[2]         
 
     def look_at(self, new_center, north_vector = None):
         r"""Change the view direction based on a new focal point.


diff -r cd3ad30dcf40fa55519318dc0eb1de63678f0035 -r d33c8b031561083ea6176b026e7c6ae1f420b3f8 yt/visualization/volume_rendering/grid_partitioner.py
--- a/yt/visualization/volume_rendering/grid_partitioner.py
+++ b/yt/visualization/volume_rendering/grid_partitioner.py
@@ -41,7 +41,8 @@
 class HomogenizedVolume(ParallelAnalysisInterface):
     bricks = None
     def __init__(self, fields = "Density", source = None, pf = None,
-                 log_fields = None, no_ghost = False):
+                 log_fields = None, no_ghost = False,
+                 max_level = 48):
         # Typically, initialized as hanging off a hierarchy.  But, not always.
         ParallelAnalysisInterface.__init__(self)
         self.no_ghost = no_ghost
@@ -54,6 +55,7 @@
         else:
             log_fields = [self.pf.field_info[field].take_log
                          for field in self.fields]
+        self.max_level = max_level
         self.log_fields = log_fields
 
     def traverse(self, back_point, front_point, image):
@@ -84,8 +86,13 @@
         PP = ProtoPrism(grid.id, grid.LeftEdge, grid.RightEdge, GF)
 
         pgs = []
+        cm = grid.child_mask.copy()
+        if grid.Level > self.max_level:
+            return pgs
+        elif grid.Level == self.max_level:
+            cm[:] = 1
         for P in PP.sweep(0):
-            sl = P.get_brick(grid.LeftEdge, grid.dds, grid.child_mask)
+            sl = P.get_brick(grid.LeftEdge, grid.dds, cm)
             if len(sl) == 0: continue
             dd = [d[sl[0][0]:sl[0][1]+1,
                     sl[1][0]:sl[1][1]+1,



https://bitbucket.org/yt_analysis/yt/changeset/e2280bc0a9f3/
changeset:   e2280bc0a9f3
branch:      yt
user:        MatthewTurk
date:        2012-06-21 19:15:47
summary:     Initial support for multicasting widgets.  URL is currently set to localhost,
for testing.
affected #:  2 files

diff -r d33c8b031561083ea6176b026e7c6ae1f420b3f8 -r e2280bc0a9f3af8e49b8898da6dfeba700ac7274 yt/gui/reason/bottle_mods.py
--- a/yt/gui/reason/bottle_mods.py
+++ b/yt/gui/reason/bottle_mods.py
@@ -33,6 +33,7 @@
 from yt.utilities.logger import ytLogger as mylog
 from yt.funcs import *
 import sys
+import urllib, urllib2
 
 route_functions = {}
 route_watchers = []
@@ -49,9 +50,10 @@
 
 class PayloadHandler(object):
     _shared_state = {}
-    _hold = False
     payloads = None
     recorded_payloads = None
+    multicast_ids = None
+    multicast_payloads = None
     lock = None
     record = False
     event = None
@@ -68,10 +70,11 @@
         if self.lock is None: self.lock = threading.Lock()
         if self.recorded_payloads is None: self.recorded_payloads = []
         if self.event is None: self.event = threading.Event()
+        if self.multicast_payloads is None: self.multicast_payloads = {}
+        if self.multicast_ids is None: self.multicast_ids = {}
 
     def deliver_payloads(self):
         with self.lock:
-            if self._hold: return []
             payloads = self.payloads
             if self.record:
                 self.recorded_payloads += self.payloads
@@ -81,11 +84,18 @@
                     sys.__stderr__.write("****    %s\n" % p['type'])
             self.payloads = []
             self.event.clear()
+            try:
+                self.deliver_multicast()
+            except Exception as exc:
+                sys.__stderr__.write("%s" % exc)
         return payloads
 
     def add_payload(self, to_add):
         with self.lock:
             self.payloads.append(to_add)
+            # Does this next part need to be in the lock?
+            if to_add.get("widget_id", None) in self.multicast_ids:
+                self.multicast_payloads[to_add["widget_id"]] = to_add
             self.count += 1
             self.event.set()
             if self.debug:
@@ -99,6 +109,19 @@
         data['widget_id'] = widget._ext_widget_id
         self.add_payload(data)
 
+    def deliver_multicast(self):
+        for widget_id in self.multicast_payloads:
+            if widget_id not in self.multicast_payloads: continue
+            server_id, session_token = self.multicast_ids[widget_id]
+            # Now we execute a post to the correct location
+            data = urllib.urlencode({
+                'payload_session_id': server_id,
+                'payload_session_token': session_token,
+                'payload_data': self.multicast_payloads[widget_id],
+                'payload_metadata': {}
+            })
+            urllib2.urlopen("http://localhost:8080/UpdatePayload", data = data)
+
 class YTRocketServer(ServerAdapter):
     server_info = {} # Hack to get back at instance vars
     def run(self, handler):


diff -r d33c8b031561083ea6176b026e7c6ae1f420b3f8 -r e2280bc0a9f3af8e49b8898da6dfeba700ac7274 yt/gui/reason/widget_store.py
--- a/yt/gui/reason/widget_store.py
+++ b/yt/gui/reason/widget_store.py
@@ -56,9 +56,14 @@
         widget._ext_widget_id = varname
         payload['data'] = widget_data
         self[varname] = widget
-        print "DELIVERING", payload
         self.payload_handler.add_payload(payload)
 
+    def activate_multicast(self, widget_id, multicast_session, multicast_token):
+        # Here we have to conduct the handshake between us and the GAE
+        self.payload_handler.multicast_ids[widget_id] = (
+            multicast_session, multicast_token)
+        mylog.info("Multicasting %s to %s", widget_id, multicast_session)
+
     def create_slice(self, pf, center, axis, field, onmax):
         if onmax: 
             center = pf.h.find_max('Density')[1]



https://bitbucket.org/yt_analysis/yt/changeset/fa90bc7d2792/
changeset:   fa90bc7d2792
branch:      yt
user:        MatthewTurk
date:        2012-06-21 19:43:17
summary:     Adding first few client side components of initiating multicast.
affected #:  1 file

diff -r e2280bc0a9f3af8e49b8898da6dfeba700ac7274 -r fa90bc7d2792ea73e829b410c78555807bcfdae8 yt/gui/reason/html/app/controller/ServerCommunication.js
--- a/yt/gui/reason/html/app/controller/ServerCommunication.js
+++ b/yt/gui/reason/html/app/controller/ServerCommunication.js
@@ -149,7 +149,62 @@
         m(args, fn);
     },
 
-    m: function() { return this.method(arguments); }
+    m: function() { return this.method(arguments); },
+
+    multicast: function(widget) {
+        /*
+           This will be two step.  The first will be to create a window that
+           allows the user to set up the MultiCast session, which will be an
+           iframe loading the GAE instance.  Then we tell our local server that
+           we want to multicast.
+        */
+        var win = Ext.create("Ext.window.Window", {
+            title: "Set up Multicasting",
+            modal: true,
+            height: 500,
+            width: 400,
+            layout: {
+                type:'vbox',
+                pack: 'start',
+                align: 'stretch',
+            },
+            items: [
+                { xtype : "component",
+                  autoEl : {
+                      tag : "iframe",
+                      src : "http://localhost:8080/CreateSession"
+                  },
+                  height: 400,
+                  width: "100%",
+                }, {
+                  xtype: "form",
+                  labelWidth: 80,
+                  frame: true,
+                  height: 100,
+                  width: "100%",
+                  items: [
+                    {
+                      xtype: 'textfield',
+                      fieldLabel: 'Session ID',
+                      itemId: 'session_id',
+                    }, {
+                      xtype: 'textfield',
+                      fieldLabel: 'Session Token',
+                      itemId: 'session_token',
+                    }, 
+                  ],
+                  buttons: [
+                      {
+                          text: 'Go', itemId: 'create',
+                      },{
+                          text: 'Cancel', itemId: 'cancel',
+                      }
+                  ],
+                }
+            ],
+        });
+        win.show();
+    },
 
 });
 



https://bitbucket.org/yt_analysis/yt/changeset/c7fa502e061e/
changeset:   c7fa502e061e
branch:      yt
user:        MatthewTurk
date:        2012-06-21 19:47:28
summary:     A few more minor changes.
affected #:  4 files

diff -r fa90bc7d2792ea73e829b410c78555807bcfdae8 -r c7fa502e061ec071e0eb19ca1e563f8fd506b064 yt/gui/reason/html/app/controller/ServerCommunication.js
--- a/yt/gui/reason/html/app/controller/ServerCommunication.js
+++ b/yt/gui/reason/html/app/controller/ServerCommunication.js
@@ -174,13 +174,13 @@
                       tag : "iframe",
                       src : "http://localhost:8080/CreateSession"
                   },
-                  height: 400,
+                  flex: 3.0,
                   width: "100%",
                 }, {
                   xtype: "form",
                   labelWidth: 80,
                   frame: true,
-                  height: 100,
+                  flex: 2.0,
                   width: "100%",
                   items: [
                     {
@@ -195,7 +195,7 @@
                   ],
                   buttons: [
                       {
-                          text: 'Go', itemId: 'create',
+                          text: 'Multicast', itemId: 'multicast',
                       },{
                           text: 'Cancel', itemId: 'cancel',
                       }


diff -r fa90bc7d2792ea73e829b410c78555807bcfdae8 -r c7fa502e061ec071e0eb19ca1e563f8fd506b064 yt/gui/reason/html/app/controller/widgets/BaseWidget.js
--- a/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
+++ b/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
@@ -114,4 +114,8 @@
         return refs;
     },
 
+    multicast: function() {
+        reason.server.multicast(this);
+    }
+
 });


diff -r fa90bc7d2792ea73e829b410c78555807bcfdae8 -r c7fa502e061ec071e0eb19ca1e563f8fd506b064 yt/gui/reason/html/app/controller/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
@@ -76,6 +76,7 @@
     widgetTriggers: [
         ['#uploadimage', 'click', 'uploadImage'],
         ['#imagepanel', 'afterrender', 'setupClickImage'],
+        ['#pannablemap', 'click', 'multicast'],
     ],
 
     executionTriggers: [


diff -r fa90bc7d2792ea73e829b410c78555807bcfdae8 -r c7fa502e061ec071e0eb19ca1e563f8fd506b064 yt/gui/reason/html/app/view/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/view/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/view/widgets/PlotWindow.js
@@ -193,6 +193,14 @@
             width: 80,
             tooltip: "Open a pannable map in a new tab",
         },{
+            xtype: 'button',
+            text: 'Multicast',
+            itemId: 'multicast',
+            x: 10,
+            y: 385,
+            width: 80,
+            tooltip: "Share this session across the Internet",
+        },{
             xtype: 'panel',
             itemId: 'rhs_panel',
             width: 300,



https://bitbucket.org/yt_analysis/yt/changeset/3e222dd32252/
changeset:   3e222dd32252
branch:      yt
user:        MatthewTurk
date:        2012-06-22 05:49:03
summary:     Removing tons of debugging statements and bringing MulticastSetup up to speed.
affected #:  10 files

diff -r c7fa502e061ec071e0eb19ca1e563f8fd506b064 -r 3e222dd32252de83f605c1377e0f20d3b0b083e8 yt/gui/reason/html/app/controller/FileOpen.js
--- a/yt/gui/reason/html/app/controller/FileOpen.js
+++ b/yt/gui/reason/html/app/controller/FileOpen.js
@@ -89,7 +89,6 @@
 
     fillStore: function(f, a) {
         var con = reason.getController("FileOpen");
-        examine = a.result;
         if(a.status == false){
           Ext.Msg.alert("Error", "Something has gone wrong.");
           con.window.destroy();


diff -r c7fa502e061ec071e0eb19ca1e563f8fd506b064 -r 3e222dd32252de83f605c1377e0f20d3b0b083e8 yt/gui/reason/html/app/controller/Logging.js
--- a/yt/gui/reason/html/app/controller/Logging.js
+++ b/yt/gui/reason/html/app/controller/Logging.js
@@ -54,7 +54,6 @@
     addLogEntry: function(text) {
         this.getLogEntriesStore().add({record: text});
         var i = this.getLogEntriesStore().getCount();
-        examine = this.getLogEntries();
         this.getLogEntries().getView().focusRow(i - 1);
     },
 });


diff -r c7fa502e061ec071e0eb19ca1e563f8fd506b064 -r 3e222dd32252de83f605c1377e0f20d3b0b083e8 yt/gui/reason/html/app/controller/ServerCommunication.js
--- a/yt/gui/reason/html/app/controller/ServerCommunication.js
+++ b/yt/gui/reason/html/app/controller/ServerCommunication.js
@@ -35,6 +35,7 @@
     extend: 'Ext.app.Controller',
     stores: ['Payloads'],
     views: ['PayloadGrid'],
+    requires: ['Reason.view.MulticastSetup'],
 
     init: function() {
         this.application.addListener({
@@ -126,7 +127,6 @@
                              action: trans.action,
                              method: trans.method});
             Ext.Msg.alert("Error", tpl);
-            examine = {result: result, e: e};
             Ext.Error.raise(tpl);
         }
         reason.fireEvent("allowinput");
@@ -137,7 +137,6 @@
         if (!m) {
             var t = "Could not identify method " + methodName;
             Ext.Msg.alert("Error", t);
-            examine = {result: result, e: e};
             Ext.Error.raise(t);
         }
         var fn;
@@ -151,58 +150,25 @@
 
     m: function() { return this.method(arguments); },
 
-    multicast: function(widget) {
+    multicast: function(widget_var) {
         /*
            This will be two step.  The first will be to create a window that
            allows the user to set up the MultiCast session, which will be an
            iframe loading the GAE instance.  Then we tell our local server that
            we want to multicast.
         */
-        var win = Ext.create("Ext.window.Window", {
-            title: "Set up Multicasting",
-            modal: true,
-            height: 500,
-            width: 400,
-            layout: {
-                type:'vbox',
-                pack: 'start',
-                align: 'stretch',
-            },
-            items: [
-                { xtype : "component",
-                  autoEl : {
-                      tag : "iframe",
-                      src : "http://localhost:8080/CreateSession"
-                  },
-                  flex: 3.0,
-                  width: "100%",
-                }, {
-                  xtype: "form",
-                  labelWidth: 80,
-                  frame: true,
-                  flex: 2.0,
-                  width: "100%",
-                  items: [
-                    {
-                      xtype: 'textfield',
-                      fieldLabel: 'Session ID',
-                      itemId: 'session_id',
-                    }, {
-                      xtype: 'textfield',
-                      fieldLabel: 'Session Token',
-                      itemId: 'session_token',
-                    }, 
-                  ],
-                  buttons: [
-                      {
-                          text: 'Multicast', itemId: 'multicast',
-                      },{
-                          text: 'Cancel', itemId: 'cancel',
-                      }
-                  ],
-                }
-            ],
-        });
+        var win = Ext.widget('multicastsetup');
+        setupMulticast = function() {
+            var cmd = Ext.String.format(
+                'widget_store.activate_multicast("{0}", "{1}", "{2}")',
+                widget_var,
+                win.query("#session_id")[0].getValue(),
+                win.query("#session_token")[0].getValue());
+            reason.server.execute(cmd);
+            win.destroy();
+        }
+        win.query('#multicast')[0].on('click', setupMulticast);
+        win.query('#cancel')[0].on('click', function(){win.destroy();});
         win.show();
     },
 


diff -r c7fa502e061ec071e0eb19ca1e563f8fd506b064 -r 3e222dd32252de83f605c1377e0f20d3b0b083e8 yt/gui/reason/html/app/controller/WidgetDirector.js
--- a/yt/gui/reason/html/app/controller/WidgetDirector.js
+++ b/yt/gui/reason/html/app/controller/WidgetDirector.js
@@ -71,7 +71,6 @@
 
     showWidgetMenu: function(treerecord, e) {
         var contextMenu = Ext.create('Ext.menu.Menu', {plain: true,});
-        examine = treerecord;
         var data = treerecord.data;
         var w;
         this.getWidgetTypesStore().each(function(record, idx) {


diff -r c7fa502e061ec071e0eb19ca1e563f8fd506b064 -r 3e222dd32252de83f605c1377e0f20d3b0b083e8 yt/gui/reason/html/app/controller/widgets/BaseWidget.js
--- a/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
+++ b/yt/gui/reason/html/app/controller/widgets/BaseWidget.js
@@ -56,7 +56,6 @@
             });
             args['control'] = control;
             args['widget'] = ww;
-            examine = {args:args, arg2: arguments, tpl:tpl};
             if((isValidFn != null) && (isValidFn(arguments) == false)) {return;}
             reason.server.execute(tpl.apply(args), true);
         };
@@ -115,7 +114,7 @@
     },
 
     multicast: function() {
-        reason.server.multicast(this);
+        reason.server.multicast(this.payload['varname']);
     }
 
 });


diff -r c7fa502e061ec071e0eb19ca1e563f8fd506b064 -r 3e222dd32252de83f605c1377e0f20d3b0b083e8 yt/gui/reason/html/app/controller/widgets/PannableMap.js
--- a/yt/gui/reason/html/app/controller/widgets/PannableMap.js
+++ b/yt/gui/reason/html/app/controller/widgets/PannableMap.js
@@ -56,7 +56,6 @@
         var ytMapURL = this.payload.data['prefix'] + '/map/{z}/{x}/{y}.png';
         this.tileLayer = new L.TileLayer(ytMapURL, {maxZoom: 18});
         this.leafletMap.addLayer(this.tileLayer)
-        examine = toRender;
     },
 
     createView: function() {


diff -r c7fa502e061ec071e0eb19ca1e563f8fd506b064 -r 3e222dd32252de83f605c1377e0f20d3b0b083e8 yt/gui/reason/html/app/controller/widgets/ParameterFile.js
--- a/yt/gui/reason/html/app/controller/widgets/ParameterFile.js
+++ b/yt/gui/reason/html/app/controller/widgets/ParameterFile.js
@@ -95,7 +95,6 @@
 
     createView: function() {
         var wd = this.payload['data'];
-        examine = wd;
         this.levelDataStore = Ext.create("Reason.store.widgets.LevelInformation");
         this.levelDataStore.loadData(wd['level_stats']);
         this.levelStatsDisplay = Ext.widget("levelstats", {


diff -r c7fa502e061ec071e0eb19ca1e563f8fd506b064 -r 3e222dd32252de83f605c1377e0f20d3b0b083e8 yt/gui/reason/html/app/controller/widgets/PhasePlot.js
--- a/yt/gui/reason/html/app/controller/widgets/PhasePlot.js
+++ b/yt/gui/reason/html/app/controller/widgets/PhasePlot.js
@@ -48,7 +48,6 @@
     ],
     
     applyPayload: function(payload) {
-        examine = payload;
         this.getImage().getEl().dom.src = 
             "data:image/png;base64," + payload['image_data'];
         this.getColorbar().getEl().dom.src=
@@ -127,7 +126,6 @@
         displayName: 'Phase Plot',
         preCreation: function(obj) {
             var widget = Ext.create(this.getName());
-            examine = obj;
             function makePlot(b, e) {
                 var conf = {
                     objname: obj.varname,
@@ -144,7 +142,6 @@
                     weightField = 'None';
                 }
                 conf['weight'] = weightField;
-                examine = {conf: conf, widget: widget};
                 var cmd = widget.templateManager.applyObject(
                     conf, 'createPhasePlot');
                 reason.server.execute(cmd);


diff -r c7fa502e061ec071e0eb19ca1e563f8fd506b064 -r 3e222dd32252de83f605c1377e0f20d3b0b083e8 yt/gui/reason/html/app/controller/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
@@ -76,7 +76,7 @@
     widgetTriggers: [
         ['#uploadimage', 'click', 'uploadImage'],
         ['#imagepanel', 'afterrender', 'setupClickImage'],
-        ['#pannablemap', 'click', 'multicast'],
+        ['#multicast', 'click', 'multicast'],
     ],
 
     executionTriggers: [
@@ -172,7 +172,6 @@
         this.getColorbar().src = "data:image/png;base64," + wd['colorbar'];
         this.fieldStore = Ext.create("Reason.store.Fields")
         this.fieldStore.loadData(wd['fields']);
-        examine = this.fieldStore;
         this.getFieldSelector().bindStore(this.fieldStore);
         this.getFieldSelector().setValue(wd['initial_field']);
         this.getTransform().setValue(wd['initial_transform']);
@@ -211,7 +210,6 @@
             }
             function togglePlotType(b, e) {
                 var plotType = win.query("#plotType")[0].getValue();
-                examine = win;
                 if (plotType == 'Projection') {
                     win.query("#weightField")[0].enable();
                     win.query("#maxDens")[0].disable();


diff -r c7fa502e061ec071e0eb19ca1e563f8fd506b064 -r 3e222dd32252de83f605c1377e0f20d3b0b083e8 yt/gui/reason/html/app/view/MulticastSetup.js
--- /dev/null
+++ b/yt/gui/reason/html/app/view/MulticastSetup.js
@@ -0,0 +1,82 @@
+/**********************************************************************
+File Open Dialog for Reason
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define('Reason.view.MulticastSetup', {
+    extend: 'Ext.window.Window',
+    alias: 'widget.multicastsetup',
+    title: "Set up Multicasting",
+    modal: true,
+    height: 500,
+    width: 800,
+    layout: {
+        type:'vbox',
+        pack: 'start',
+        align: 'stretch',
+    },
+    items: [
+        { xtype : "component",
+          autoEl : {
+              tag : "iframe",
+              src : "http://localhost:8080/CreateSession"
+          },
+          flex: 1.0,
+          width: "100%",
+        }, {
+          xtype: "form",
+          labelWidth: 80,
+          frame: true,
+          height: 120,
+          width: "100%",
+          items: [
+            {
+              xtype: 'textfield',
+              fieldLabel: 'Session ID',
+              itemId: 'session_id',
+              width: 300,
+            }, {
+              xtype: 'textfield',
+              fieldLabel: 'Session Token',
+              itemId: 'session_token',
+              width: 300,
+            }, 
+          ],
+          buttons: [
+              {
+                  text: 'Multicast', itemId: 'multicast',
+              },{
+                  text: 'Cancel', itemId: 'cancel',
+              }
+          ],
+        }
+    ],
+});
+
+



https://bitbucket.org/yt_analysis/yt/changeset/88863817c19c/
changeset:   88863817c19c
branch:      yt
user:        MatthewTurk
date:        2012-06-22 12:27:52
summary:     multicast view creator
affected #:  1 file

diff -r 3e222dd32252de83f605c1377e0f20d3b0b083e8 -r 88863817c19c940a771b87d998bb36d869d66b95 yt/gui/reason/html/app/controller/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
@@ -181,6 +181,19 @@
         return this.plotWindowView;
     },
 
+    createMulticastView: function() {
+        this.plotWindowView = Ext.widget("plotwindow", {
+            varname = null,
+            title: "Multicast View",
+        });
+        Ext.each(this.widgetTriggers, function(trigger, index, all) {
+            this.plotWindowView.query(trigger[0])[0].disable();
+        });
+        Ext.each(this.executionTriggers, function(trigger, index, all) {
+            this.plotWindowView.query(trigger[0])[0].disable();
+        });
+    },
+
     statics: {
         widgetName: 'plot_window',
         supportsDataObjects: false,



https://bitbucket.org/yt_analysis/yt/changeset/837a18a92fc7/
changeset:   837a18a92fc7
branch:      yt
user:        MatthewTurk
date:        2012-06-22 12:28:30
summary:     Syntax fix
affected #:  1 file

diff -r 88863817c19c940a771b87d998bb36d869d66b95 -r 837a18a92fc76e395c1642aa216939c0d6627c95 yt/gui/reason/html/app/controller/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
@@ -183,7 +183,7 @@
 
     createMulticastView: function() {
         this.plotWindowView = Ext.widget("plotwindow", {
-            varname = null,
+            varname: null,
             title: "Multicast View",
         });
         Ext.each(this.widgetTriggers, function(trigger, index, all) {



https://bitbucket.org/yt_analysis/yt/changeset/024b6c4ad4d1/
changeset:   024b6c4ad4d1
branch:      yt
user:        samskillman
date:        2012-06-22 20:54:35
summary:     Modifying ordering of grid_corners.
affected #:  1 file

diff -r 837a18a92fc76e395c1642aa216939c0d6627c95 -r 024b6c4ad4d1af7c505be484c5bc70228b7198b5 yt/data_objects/hierarchy.py
--- a/yt/data_objects/hierarchy.py
+++ b/yt/data_objects/hierarchy.py
@@ -370,11 +370,11 @@
           [self.grid_left_edge[:,0], self.grid_left_edge[:,1], self.grid_left_edge[:,2]],
           [self.grid_right_edge[:,0], self.grid_left_edge[:,1], self.grid_left_edge[:,2]],
           [self.grid_right_edge[:,0], self.grid_right_edge[:,1], self.grid_left_edge[:,2]],
+          [self.grid_left_edge[:,0], self.grid_right_edge[:,1], self.grid_left_edge[:,2]],
+          [self.grid_left_edge[:,0], self.grid_left_edge[:,1], self.grid_right_edge[:,2]],
+          [self.grid_right_edge[:,0], self.grid_left_edge[:,1], self.grid_right_edge[:,2]],
           [self.grid_right_edge[:,0], self.grid_right_edge[:,1], self.grid_right_edge[:,2]],
           [self.grid_left_edge[:,0], self.grid_right_edge[:,1], self.grid_right_edge[:,2]],
-          [self.grid_left_edge[:,0], self.grid_left_edge[:,1], self.grid_right_edge[:,2]],
-          [self.grid_right_edge[:,0], self.grid_left_edge[:,1], self.grid_right_edge[:,2]],
-          [self.grid_left_edge[:,0], self.grid_right_edge[:,1], self.grid_left_edge[:,2]],
         ], dtype='float64')
 
     def print_stats(self):



https://bitbucket.org/yt_analysis/yt/changeset/e4b6680ac7b8/
changeset:   e4b6680ac7b8
branch:      yt
user:        samskillman
date:        2012-06-23 00:13:37
summary:     Adding a RenderScene, and widget builders to get data
affected #:  2 files

diff -r 024b6c4ad4d1af7c505be484c5bc70228b7198b5 -r e4b6680ac7b8522f9b643c71792936ed12f13c8f yt/gui/reason/widget_builders.py
--- /dev/null
+++ b/yt/gui/reason/widget_builders.py
@@ -0,0 +1,144 @@
+"""
+These widget objects provide the interaction to yt tasks.
+
+Author: Samuel Skillman <samskillman at gmail.com>
+Affiliation: University of Colorado at Boulder
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+"""
+from yt.mods import *
+import weakref
+
+class RenderingScene(object):
+    _camera = None
+    _tf = None
+    
+    def __init__(self, pf, camera=None, tf=None):
+        self.pf = weakref.proxy(pf)
+        self._camera = camera
+        self._tf = tf
+
+        self.center = self.pf.domain_center
+        self.normal_vector = na.array([0.7,1.0,0.3])
+        self.north_vector = [0.,0.,1.]
+        self.steady_north = True
+        self.fields = ['Density']
+        self.log_fields = [True]
+        self.l_max = 0
+        self.mi = None
+        self.ma = None
+        if self._tf is None:
+            self._new_tf(self.pf)
+
+        if self._camera is None:
+            self._new_camera(self.pf)
+
+    def _new_tf(self, pf, mi=None, ma=None, nbins=1024):
+        if mi is None or ma is None:
+            roi = self.pf.h.region(self.center, self.center-self.width, self.center+self.width)
+            self.mi, self.ma = roi.quantities['Extrema'](self.fields[0])[0]
+            if self.log_fields[0]:
+                self.mi, self.ma = na.log10(self.mi), na.log10(self.ma)
+
+        self._tf = ColorTransferFunction((self.mi-2, self.ma+2), nbins=nbins)
+
+    def add_contours(self, n_contours=7, contour_width=0.05, colormap='kamae'):
+        self._tf.add_layers(n_contours=n_contours ,w=contour_width,
+                                  col_bounds = (self.mi,self.ma), 
+                                  colormap=colormap)
+
+    def _new_camera(self, pf):
+        del self._camera
+        self._camera = self.pf.camera(self.center, self.normal_vector, 
+                                      self.width, self.resolution, self._tf,
+                                      north_vector=self.north_vector,
+                                      steady_north=self.steady_north,
+                                      fields=self.fields, log_fields=self.log_fields,
+                                      l_max=self.l_max)
+    def snapshot(self):
+        return self._camera.snapshot()
+
+
+def get_corners(pf, max_level=Non):
+    corners = pf.h.grid_corners.tolist()
+    levels = pf.h.grid_levels.to_list()
+    return corners, levels    
+
+def get_grid_vertices(pf, max_level=None)
+    if max_level is None: max_level = pf.h.max_level
+    fns = []
+    for lvl in range(max_level):
+        fn = "%s_lvl_%02i_grids.vtk"%(pf, lvl)
+        f = open(fn, "w")
+
+        f.write("""# vtk DataFile Version 3.0
+        vtk output
+        ASCII
+        DATASET POLYDATA
+        POINTS %s float
+        """ % (pf.h.num_grids * 8))
+
+        for gi in xrange(pf.h.num_grids):
+            if pf.h.grid_levels[gi][0] != lvl: continue
+            gc = pf.h.grid_corners[:, :, gi] * 100.0
+            for i in range(8):
+                f.write("%0.9f %0.9f %0.9f\n" % (gc[i, 0], gc[i, 1], gc[i, 2]))
+
+        f.write("LINES %s %s\n" % (pf.h.num_grids * 12, 3 * pf.h.num_grids * 12))
+
+        order1 = (0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3)
+        order2 = (1, 2, 3, 0, 5, 6, 7, 4, 4, 5, 6, 7)
+
+        for gi in xrange(pf.h.num_grids):
+            if pf.h.grid_levels[gi][0] != lvl: continue
+            offset = 8 * gi
+            for p1, p2 in zip(order1, order2):
+                f.write("2 %s %s\n" % (p1 + offset, p2 + offset))
+        f.close()
+        fns.append(fn)
+    return fn
+
+def get_isocontour(pf, field, value=None):
+
+    dd = pf.h.all_data()
+    if value is None:
+        mi, ma = na.log10(dd.quantities["Extrema"]("Density")[0])
+        value = 10.**((mi + ma)/2.)
+    vert = dd.extract_isocontours("Density", value)
+    na.multiply(vert, 100, vert)
+
+    fn = "%s_surface.vtk" % pf
+    f = open(fn, "w")
+    f.write("vtk output\nASCII\nDATASET POLYDATA\nPOINTS %s float\n" % (vert.shape[0]))
+    for v in vert:
+        f.write("%0.14f %0.14f %0.14f\n" % (v[0], v[1], v[2]))
+    f.write("VERTICES %s %s\n" % (vert.shape[0]/3, vert.shape[0] + vert.shape[0]/3))
+    for i in range(vert.shape[0]/3):
+        f.write("3 %i %i %i\n" % (i*3, i*3+1, i*3+2))
+    f.close()
+    return fn
+
+def get_streamlines(pf):
+    from yt.visualization.api import Streamlines
+    streamlines = Streamlines(pf, pf.domain_center) 
+    streamlines.integrate_through_volume()
+    stream = streamlines.path(0)
+    matplotlib.pylab.semilogy(stream['t'], stream['Density'], '-x')
+
+


diff -r 024b6c4ad4d1af7c505be484c5bc70228b7198b5 -r e4b6680ac7b8522f9b643c71792936ed12f13c8f yt/gui/reason/widget_store.py
--- a/yt/gui/reason/widget_store.py
+++ b/yt/gui/reason/widget_store.py
@@ -26,6 +26,7 @@
 from yt.mods import *
 import weakref
 from .bottle_mods import PayloadHandler, lockit
+from .widget_builders import RenderingScene 
 from yt.visualization.plot_window import PWViewerExtJS
 import uuid
 
@@ -159,6 +160,14 @@
                        'metadata_string': mds}
         self._add_widget(pp, widget_data)
 
+    def create_scene(self, pf):
+        '''Creates 3D XTK-based scene'''
+        widget = SceneWidget()
+        widget_data = {'render': widget._add_volume_rendering(),
+                      }
+        self._add_widget(widget, widget_data)
+
+
 class ParameterFileWidget(object):
     _ext_widget_id = None
     _widget_name = "parameterfile"
@@ -202,3 +211,32 @@
             {'ptype':'field_info',
              'field_source': self.pf.field_info[field].get_source() })
         return
+
+class SceneWidget(object):
+    _ext_widget_id = None
+    _widget_name = "scene"
+    _rendering_scene = None
+
+    def __init__(self, pf):
+        self.pf = weakref.proxy(pf)
+
+    def add_volume_rendering(self):
+        self._rendering_scene = RenderingScene(self.pf, None, None)
+
+    def deliver_rendering(self, scene_config):
+        ph = PayloadHandler()
+        ph.widget_payload(self, {'ptype':'rendering',
+                                 'image':self._rendering_scene.snapshot()})
+        return
+
+    def deliver_gridlines(self):
+        ph = PayloadHandler()
+        ph.widget_payload(self, {'ptype':'grid_lines',
+                                 'vertices': get_grid_vertices(),
+                                 'colors': get_grid_colors()})
+        return
+
+    def deliver_streamlines(self):
+        pf = PayloadHandler()
+        pass
+



https://bitbucket.org/yt_analysis/yt/changeset/8f1bf011d89e/
changeset:   8f1bf011d89e
branch:      yt
user:        MatthewTurk
date:        2012-06-22 22:46:43
summary:     Initial 3D scene import.  This is exciting.
affected #:  4 files

diff -r 024b6c4ad4d1af7c505be484c5bc70228b7198b5 -r 8f1bf011d89e6fc0f85e697982f8e377cfe59b9a yt/gui/reason/html/app/controller/WidgetDirector.js
--- a/yt/gui/reason/html/app/controller/WidgetDirector.js
+++ b/yt/gui/reason/html/app/controller/WidgetDirector.js
@@ -32,6 +32,7 @@
                "Reason.controller.widgets.ParameterFile",
                "Reason.controller.widgets.PannableMap",
                "Reason.controller.widgets.PhasePlot",
+               "Reason.controller.widgets.Scene",
     ],
     stores: ['WidgetTypes', 'WidgetInstances'],
     views: ['WidgetTypesGrid', 'WidgetInstancesGrid'],


diff -r 024b6c4ad4d1af7c505be484c5bc70228b7198b5 -r 8f1bf011d89e6fc0f85e697982f8e377cfe59b9a yt/gui/reason/html/app/controller/widgets/Scene.js
--- /dev/null
+++ b/yt/gui/reason/html/app/controller/widgets/Scene.js
@@ -0,0 +1,78 @@
+/**********************************************************************
+The 3D Scene Widget
+
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Authors: Samuel Skillman <samskillman at gmail.com>
+Affiliation: University of Colorado at Boulder
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2012 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define("Reason.controller.widgets.Scene", {
+    extend: 'Reason.controller.widgets.BaseWidget',
+    requires: ['Reason.view.widgets.Scene'],
+    templates: {
+        createScene: 'widget_store.create_scene({varname})',
+    },
+
+    /* These call functions on the controller object */
+    widgetTriggers: [
+    ],
+
+    /* These call templates */
+    executionTriggers: [
+    ],
+
+    /* ref: and selector: */
+    viewRefs: [
+    ],
+
+    /* key: , shift: and tpl: */
+    keyTriggers: [
+    ],
+
+    applyPayload: function(payload) {
+    },
+
+    createView: function() {
+        var wd = this.payload['data'];
+        this.dataView = Ext.widget("scene",{
+            title: wd['title'],
+        });
+        this.createMyRefs(this.dataView.id);
+        this.applyExecuteHandlers(this.dataView);
+        return this.dataView;
+    },
+
+    statics: {
+        widgetName: '3d_scene',
+        supportsDataObjects: false,
+        supportsParameterFiles: true,
+        displayName: '3D Plot',
+        preCreation: function(obj) {
+            var widget = Ext.create(this.getName());
+            var cmd = widget.templateManager.applyObject(
+                obj, 'createDisplay');
+            reason.server.execute(cmd);
+        },
+
+    },
+
+});


diff -r 024b6c4ad4d1af7c505be484c5bc70228b7198b5 -r 8f1bf011d89e6fc0f85e697982f8e377cfe59b9a yt/gui/reason/html/app/view/widgets/Scene.js
--- /dev/null
+++ b/yt/gui/reason/html/app/view/widgets/Scene.js
@@ -0,0 +1,105 @@
+/**********************************************************************
+The Plot Window Widget View
+
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Authors: Samuel Skillman <samskillman at gmail.com>
+Affiliation: University of Colorado at Boulder
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2012 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define("Reason.view.widgets.Scene", {
+    extend: 'Ext.panel.Panel',
+    title: 'This should not be visible.',
+    alias: 'widget.scene',
+    iconCls: 'graph',
+    autoScroll: true,
+    layout: 'absolute',
+    width: '100%',
+    height: '100%',
+    closable: true,
+
+    items: [ 
+        { xtype:'panel',
+          itemId: 'scenepanel',
+          x: 10,
+          y: 10,
+          width: 450,
+          height: 450,
+        }, {
+            xtype: 'multislider',
+            itemId: 'cameraPathSlider',
+            minValue: 0,
+            maxValue: 100,
+            increment: 1,
+            x: 10, y: 460,
+            width: 450,
+        },{
+            xtype: 'panel',
+            itemId: 'rhs_panel',
+            width: 300,
+            height: 450,
+            x: 470, y: 10,
+            layout: {
+                type: 'vbox',
+                align:'stretch',
+                pack:'start',
+            },
+            items: [
+                {
+                  xtype: 'tabpanel',
+                  title: 'Scene Editor',
+                  itemId: 'editor_panel',
+                  flex: 1.0,
+                  activeTab: 0,
+                  items: [
+                {
+                  xtype: 'panel',
+                  title: 'Data Editor',
+                  itemId: 'plot_edit',
+                  layout: 'absolute',
+                  flex: 1,
+                  items : [
+                  ]
+                }, {
+                  xtype: 'panel',
+                  title: 'Widgets',
+                  itemId: 'contour_edit',
+                  style: {fontFamily: '"Inconsolata", monospace'},
+                  layout: 'absolute',
+                  flex: 1,
+                  items : [
+                  ]
+                }, {
+                  xtype: 'panel',
+                  title: 'Camera Path',
+                  itemId: 'contour_edit',
+                  style: {fontFamily: '"Inconsolata", monospace'},
+                  layout: 'absolute',
+                  flex: 1,
+                  items : [
+                  ]
+                }
+                ] } /* tabpanel items and entry */
+                ]
+        }
+    ],
+});
+


diff -r 024b6c4ad4d1af7c505be484c5bc70228b7198b5 -r 8f1bf011d89e6fc0f85e697982f8e377cfe59b9a yt/gui/reason/html/index.html
--- a/yt/gui/reason/html/index.html
+++ b/yt/gui/reason/html/index.html
@@ -21,6 +21,9 @@
     <script type="text/javascript" src="reason/resources/leaflet/leaflet.js"></script><link rel="stylesheet" href="reason/resources/leaflet/leaflet.css" />
 
+    <!-- XTK STUFF -->
+    <script type="text/javascript" src="reason/xtk_edge.js"></script>
+
 </head><body></body>



https://bitbucket.org/yt_analysis/yt/changeset/b1bc5dee4a33/
changeset:   b1bc5dee4a33
branch:      yt
user:        MatthewTurk
date:        2012-06-23 00:14:28
summary:     Initial XTK setup
affected #:  1 file

diff -r 8f1bf011d89e6fc0f85e697982f8e377cfe59b9a -r b1bc5dee4a33894b00a3a5f97477c9cae156d6e4 yt/gui/reason/html/app/controller/widgets/Scene.js
--- a/yt/gui/reason/html/app/controller/widgets/Scene.js
+++ b/yt/gui/reason/html/app/controller/widgets/Scene.js
@@ -34,6 +34,7 @@
 
     /* These call functions on the controller object */
     widgetTriggers: [
+        ["#scenepanel", "afterrender", "setupXTK"],
     ],
 
     /* These call templates */
@@ -42,6 +43,7 @@
 
     /* ref: and selector: */
     viewRefs: [
+        { ref:'scenePanel', selector: '#scenepanel' },
     ],
 
     /* key: , shift: and tpl: */
@@ -72,7 +74,13 @@
                 obj, 'createDisplay');
             reason.server.execute(cmd);
         },
+    },
 
+    setupXTK: function() {
+        var sp = this.getScenePanel();
+        this.renderer = new X.renderer3D();
+        this.renderer.container = sp.getEl().dom;
+        this.renderer.init();
     },
 
 });



https://bitbucket.org/yt_analysis/yt/changeset/d8ab38e58b4b/
changeset:   d8ab38e58b4b
branch:      yt
user:        MatthewTurk
date:        2012-06-23 00:15:04
summary:     Merge
affected #:  2 files

diff -r b1bc5dee4a33894b00a3a5f97477c9cae156d6e4 -r d8ab38e58b4bcc4de7e94e3f8346e307a24a71fa yt/gui/reason/widget_builders.py
--- /dev/null
+++ b/yt/gui/reason/widget_builders.py
@@ -0,0 +1,144 @@
+"""
+These widget objects provide the interaction to yt tasks.
+
+Author: Samuel Skillman <samskillman at gmail.com>
+Affiliation: University of Colorado at Boulder
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+"""
+from yt.mods import *
+import weakref
+
+class RenderingScene(object):
+    _camera = None
+    _tf = None
+    
+    def __init__(self, pf, camera=None, tf=None):
+        self.pf = weakref.proxy(pf)
+        self._camera = camera
+        self._tf = tf
+
+        self.center = self.pf.domain_center
+        self.normal_vector = na.array([0.7,1.0,0.3])
+        self.north_vector = [0.,0.,1.]
+        self.steady_north = True
+        self.fields = ['Density']
+        self.log_fields = [True]
+        self.l_max = 0
+        self.mi = None
+        self.ma = None
+        if self._tf is None:
+            self._new_tf(self.pf)
+
+        if self._camera is None:
+            self._new_camera(self.pf)
+
+    def _new_tf(self, pf, mi=None, ma=None, nbins=1024):
+        if mi is None or ma is None:
+            roi = self.pf.h.region(self.center, self.center-self.width, self.center+self.width)
+            self.mi, self.ma = roi.quantities['Extrema'](self.fields[0])[0]
+            if self.log_fields[0]:
+                self.mi, self.ma = na.log10(self.mi), na.log10(self.ma)
+
+        self._tf = ColorTransferFunction((self.mi-2, self.ma+2), nbins=nbins)
+
+    def add_contours(self, n_contours=7, contour_width=0.05, colormap='kamae'):
+        self._tf.add_layers(n_contours=n_contours ,w=contour_width,
+                                  col_bounds = (self.mi,self.ma), 
+                                  colormap=colormap)
+
+    def _new_camera(self, pf):
+        del self._camera
+        self._camera = self.pf.camera(self.center, self.normal_vector, 
+                                      self.width, self.resolution, self._tf,
+                                      north_vector=self.north_vector,
+                                      steady_north=self.steady_north,
+                                      fields=self.fields, log_fields=self.log_fields,
+                                      l_max=self.l_max)
+    def snapshot(self):
+        return self._camera.snapshot()
+
+
+def get_corners(pf, max_level=Non):
+    corners = pf.h.grid_corners.tolist()
+    levels = pf.h.grid_levels.to_list()
+    return corners, levels    
+
+def get_grid_vertices(pf, max_level=None)
+    if max_level is None: max_level = pf.h.max_level
+    fns = []
+    for lvl in range(max_level):
+        fn = "%s_lvl_%02i_grids.vtk"%(pf, lvl)
+        f = open(fn, "w")
+
+        f.write("""# vtk DataFile Version 3.0
+        vtk output
+        ASCII
+        DATASET POLYDATA
+        POINTS %s float
+        """ % (pf.h.num_grids * 8))
+
+        for gi in xrange(pf.h.num_grids):
+            if pf.h.grid_levels[gi][0] != lvl: continue
+            gc = pf.h.grid_corners[:, :, gi] * 100.0
+            for i in range(8):
+                f.write("%0.9f %0.9f %0.9f\n" % (gc[i, 0], gc[i, 1], gc[i, 2]))
+
+        f.write("LINES %s %s\n" % (pf.h.num_grids * 12, 3 * pf.h.num_grids * 12))
+
+        order1 = (0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3)
+        order2 = (1, 2, 3, 0, 5, 6, 7, 4, 4, 5, 6, 7)
+
+        for gi in xrange(pf.h.num_grids):
+            if pf.h.grid_levels[gi][0] != lvl: continue
+            offset = 8 * gi
+            for p1, p2 in zip(order1, order2):
+                f.write("2 %s %s\n" % (p1 + offset, p2 + offset))
+        f.close()
+        fns.append(fn)
+    return fn
+
+def get_isocontour(pf, field, value=None):
+
+    dd = pf.h.all_data()
+    if value is None:
+        mi, ma = na.log10(dd.quantities["Extrema"]("Density")[0])
+        value = 10.**((mi + ma)/2.)
+    vert = dd.extract_isocontours("Density", value)
+    na.multiply(vert, 100, vert)
+
+    fn = "%s_surface.vtk" % pf
+    f = open(fn, "w")
+    f.write("vtk output\nASCII\nDATASET POLYDATA\nPOINTS %s float\n" % (vert.shape[0]))
+    for v in vert:
+        f.write("%0.14f %0.14f %0.14f\n" % (v[0], v[1], v[2]))
+    f.write("VERTICES %s %s\n" % (vert.shape[0]/3, vert.shape[0] + vert.shape[0]/3))
+    for i in range(vert.shape[0]/3):
+        f.write("3 %i %i %i\n" % (i*3, i*3+1, i*3+2))
+    f.close()
+    return fn
+
+def get_streamlines(pf):
+    from yt.visualization.api import Streamlines
+    streamlines = Streamlines(pf, pf.domain_center) 
+    streamlines.integrate_through_volume()
+    stream = streamlines.path(0)
+    matplotlib.pylab.semilogy(stream['t'], stream['Density'], '-x')
+
+


diff -r b1bc5dee4a33894b00a3a5f97477c9cae156d6e4 -r d8ab38e58b4bcc4de7e94e3f8346e307a24a71fa yt/gui/reason/widget_store.py
--- a/yt/gui/reason/widget_store.py
+++ b/yt/gui/reason/widget_store.py
@@ -26,6 +26,7 @@
 from yt.mods import *
 import weakref
 from .bottle_mods import PayloadHandler, lockit
+from .widget_builders import RenderingScene 
 from yt.visualization.plot_window import PWViewerExtJS
 import uuid
 
@@ -159,6 +160,14 @@
                        'metadata_string': mds}
         self._add_widget(pp, widget_data)
 
+    def create_scene(self, pf):
+        '''Creates 3D XTK-based scene'''
+        widget = SceneWidget()
+        widget_data = {'render': widget._add_volume_rendering(),
+                      }
+        self._add_widget(widget, widget_data)
+
+
 class ParameterFileWidget(object):
     _ext_widget_id = None
     _widget_name = "parameterfile"
@@ -202,3 +211,32 @@
             {'ptype':'field_info',
              'field_source': self.pf.field_info[field].get_source() })
         return
+
+class SceneWidget(object):
+    _ext_widget_id = None
+    _widget_name = "scene"
+    _rendering_scene = None
+
+    def __init__(self, pf):
+        self.pf = weakref.proxy(pf)
+
+    def add_volume_rendering(self):
+        self._rendering_scene = RenderingScene(self.pf, None, None)
+
+    def deliver_rendering(self, scene_config):
+        ph = PayloadHandler()
+        ph.widget_payload(self, {'ptype':'rendering',
+                                 'image':self._rendering_scene.snapshot()})
+        return
+
+    def deliver_gridlines(self):
+        ph = PayloadHandler()
+        ph.widget_payload(self, {'ptype':'grid_lines',
+                                 'vertices': get_grid_vertices(),
+                                 'colors': get_grid_colors()})
+        return
+
+    def deliver_streamlines(self):
+        pf = PayloadHandler()
+        pass
+



https://bitbucket.org/yt_analysis/yt/changeset/0b66a0670baf/
changeset:   0b66a0670baf
branch:      yt
user:        MatthewTurk
date:        2012-06-23 00:38:24
summary:     Fixing a few bugs and creating a 3D scene.
affected #:  4 files

diff -r d8ab38e58b4bcc4de7e94e3f8346e307a24a71fa -r 0b66a0670bafd89a8f624a878e5fcb9c44361dad yt/gui/reason/html/app/controller/widgets/Scene.js
--- a/yt/gui/reason/html/app/controller/widgets/Scene.js
+++ b/yt/gui/reason/html/app/controller/widgets/Scene.js
@@ -51,6 +51,7 @@
     ],
 
     applyPayload: function(payload) {
+        
     },
 
     createView: function() {
@@ -64,22 +65,24 @@
     },
 
     statics: {
-        widgetName: '3d_scene',
+        widgetName: 'scene',
         supportsDataObjects: false,
         supportsParameterFiles: true,
         displayName: '3D Plot',
         preCreation: function(obj) {
             var widget = Ext.create(this.getName());
             var cmd = widget.templateManager.applyObject(
-                obj, 'createDisplay');
+                obj, 'createScene');
+            console.log("Executing " + cmd);
             reason.server.execute(cmd);
         },
     },
 
     setupXTK: function() {
-        var sp = this.getScenePanel();
+        var toRender = this.getScenePanel().getEl().dom.childNodes[0];
+        toRender.classList.add("XTKScene");
         this.renderer = new X.renderer3D();
-        this.renderer.container = sp.getEl().dom;
+        this.renderer.container = toRender;
         this.renderer.init();
     },
 


diff -r d8ab38e58b4bcc4de7e94e3f8346e307a24a71fa -r 0b66a0670bafd89a8f624a878e5fcb9c44361dad yt/gui/reason/html/resources/css/style.css
--- a/yt/gui/reason/html/resources/css/style.css
+++ b/yt/gui/reason/html/resources/css/style.css
@@ -71,3 +71,7 @@
     padding-left: 10px;
     padding-right: 10px;
 }
+
+div.XTKscene {
+    background-color:#000;
+}


diff -r d8ab38e58b4bcc4de7e94e3f8346e307a24a71fa -r 0b66a0670bafd89a8f624a878e5fcb9c44361dad yt/gui/reason/widget_builders.py
--- a/yt/gui/reason/widget_builders.py
+++ b/yt/gui/reason/widget_builders.py
@@ -75,12 +75,12 @@
         return self._camera.snapshot()
 
 
-def get_corners(pf, max_level=Non):
+def get_corners(pf, max_level=None):
     corners = pf.h.grid_corners.tolist()
     levels = pf.h.grid_levels.to_list()
     return corners, levels    
 
-def get_grid_vertices(pf, max_level=None)
+def get_grid_vertices(pf, max_level=None):
     if max_level is None: max_level = pf.h.max_level
     fns = []
     for lvl in range(max_level):


diff -r d8ab38e58b4bcc4de7e94e3f8346e307a24a71fa -r 0b66a0670bafd89a8f624a878e5fcb9c44361dad yt/gui/reason/widget_store.py
--- a/yt/gui/reason/widget_store.py
+++ b/yt/gui/reason/widget_store.py
@@ -162,9 +162,8 @@
 
     def create_scene(self, pf):
         '''Creates 3D XTK-based scene'''
-        widget = SceneWidget()
-        widget_data = {'render': widget._add_volume_rendering(),
-                      }
+        widget = SceneWidget(pf)
+        widget_data = {'title':'Scene for %s' % pf}
         self._add_widget(widget, widget_data)
 
 
@@ -221,6 +220,7 @@
         self.pf = weakref.proxy(pf)
 
     def add_volume_rendering(self):
+        return None
         self._rendering_scene = RenderingScene(self.pf, None, None)
 
     def deliver_rendering(self, scene_config):



https://bitbucket.org/yt_analysis/yt/changeset/4b8216200c3e/
changeset:   4b8216200c3e
branch:      yt
user:        MatthewTurk
date:        2012-06-23 01:00:39
summary:     Grid lines can now be delivered.
affected #:  3 files

diff -r 0b66a0670bafd89a8f624a878e5fcb9c44361dad -r 4b8216200c3eb78638296ffe293106607b833529 yt/gui/reason/html/app/controller/widgets/Scene.js
--- a/yt/gui/reason/html/app/controller/widgets/Scene.js
+++ b/yt/gui/reason/html/app/controller/widgets/Scene.js
@@ -51,7 +51,12 @@
     ],
 
     applyPayload: function(payload) {
-        
+        if (payload['ptype'] == 'grid_lines') {
+            this.addGridLines(payload['corners'], payload['levels']);
+        } else {
+            console.log("Unknown payload type received for 3D scene: " +
+                        payload['ptype']);
+        }
     },
 
     createView: function() {
@@ -61,6 +66,7 @@
         });
         this.createMyRefs(this.dataView.id);
         this.applyExecuteHandlers(this.dataView);
+        this.widgets = [];
         return this.dataView;
     },
 
@@ -86,4 +92,31 @@
         this.renderer.init();
     },
 
+    addGridLines: function(corners, levels) {
+        var grids = new X.mesh();
+        this.widgets.push(grids);
+        grids.ga = "LINES";
+        var p = grids.points;
+        var n = grids.normals;
+        var ii = 0;
+        var i;
+        var order1 = [0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3];
+        var order2 = [1, 2, 3, 0, 5, 6, 7, 4, 4, 5, 6, 7];
+        examine = corners;
+        Ext.each(levels, function(level, index, allLevels) {
+            for (i = 0; i < 12; i = i + 1) {
+                n.add(1.0, 0.0, 0.0);
+                n.add(1.0, 0.0, 0.0);
+                p.add(corners[order1[i]][0][index],
+                      corners[order1[i]][1][index],
+                      corners[order1[i]][2][index]);
+                p.add(corners[order2[i]][0][index],
+                      corners[order2[i]][1][index],
+                      corners[order2[i]][2][index]);
+            }
+        });
+        this.renderer.add(grids);
+        this.renderer.render();
+    }
+
 });


diff -r 0b66a0670bafd89a8f624a878e5fcb9c44361dad -r 4b8216200c3eb78638296ffe293106607b833529 yt/gui/reason/widget_builders.py
--- a/yt/gui/reason/widget_builders.py
+++ b/yt/gui/reason/widget_builders.py
@@ -76,8 +76,8 @@
 
 
 def get_corners(pf, max_level=None):
-    corners = pf.h.grid_corners.tolist()
-    levels = pf.h.grid_levels.to_list()
+    corners = (100*pf.h.grid_corners).tolist()
+    levels = pf.h.grid_levels.tolist()
     return corners, levels    
 
 def get_grid_vertices(pf, max_level=None):


diff -r 0b66a0670bafd89a8f624a878e5fcb9c44361dad -r 4b8216200c3eb78638296ffe293106607b833529 yt/gui/reason/widget_store.py
--- a/yt/gui/reason/widget_store.py
+++ b/yt/gui/reason/widget_store.py
@@ -26,7 +26,7 @@
 from yt.mods import *
 import weakref
 from .bottle_mods import PayloadHandler, lockit
-from .widget_builders import RenderingScene 
+from .widget_builders import RenderingScene, get_corners
 from yt.visualization.plot_window import PWViewerExtJS
 import uuid
 
@@ -231,9 +231,10 @@
 
     def deliver_gridlines(self):
         ph = PayloadHandler()
+        corners, levels = get_corners(self.pf)
         ph.widget_payload(self, {'ptype':'grid_lines',
-                                 'vertices': get_grid_vertices(),
-                                 'colors': get_grid_colors()})
+                                 'corners': corners,
+                                 'levels': levels})
         return
 
     def deliver_streamlines(self):



https://bitbucket.org/yt_analysis/yt/changeset/7e09c4f1b1e7/
changeset:   7e09c4f1b1e7
branch:      yt
user:        MatthewTurk
date:        2012-06-23 03:49:01
summary:     Initial grid delivery works.
affected #:  4 files

diff -r 4b8216200c3eb78638296ffe293106607b833529 -r 7e09c4f1b1e708ce3d7507e9096d8834daab3cd1 yt/gui/reason/html/app/controller/widgets/Scene.js
--- a/yt/gui/reason/html/app/controller/widgets/Scene.js
+++ b/yt/gui/reason/html/app/controller/widgets/Scene.js
@@ -30,6 +30,7 @@
     requires: ['Reason.view.widgets.Scene'],
     templates: {
         createScene: 'widget_store.create_scene({varname})',
+        deliverGrids: 'widget_store["{widget.varname}"].deliver_gridlines()',
     },
 
     /* These call functions on the controller object */
@@ -39,6 +40,7 @@
 
     /* These call templates */
     executionTriggers: [
+        ["#deliverGrids", "click", "deliverGrids"],
     ],
 
     /* ref: and selector: */
@@ -63,6 +65,7 @@
         var wd = this.payload['data'];
         this.dataView = Ext.widget("scene",{
             title: wd['title'],
+            varname: this.payload['varname'],
         });
         this.createMyRefs(this.dataView.id);
         this.applyExecuteHandlers(this.dataView);


diff -r 4b8216200c3eb78638296ffe293106607b833529 -r 7e09c4f1b1e708ce3d7507e9096d8834daab3cd1 yt/gui/reason/html/app/view/widgets/Scene.js
--- a/yt/gui/reason/html/app/view/widgets/Scene.js
+++ b/yt/gui/reason/html/app/view/widgets/Scene.js
@@ -37,12 +37,14 @@
     closable: true,
 
     items: [ 
-        { xtype:'panel',
-          itemId: 'scenepanel',
+        {
+          xtype:'panel',
+          layout: 'absolute',
           x: 10,
           y: 10,
           width: 450,
           height: 450,
+          itemId: 'scenepanel',
         }, {
             xtype: 'multislider',
             itemId: 'cameraPathSlider',
@@ -73,16 +75,20 @@
                 {
                   xtype: 'panel',
                   title: 'Data Editor',
-                  itemId: 'plot_edit',
+                  itemId: 'data_edit',
                   layout: 'absolute',
                   flex: 1,
                   items : [
+                    {
+                        xtype: 'button',
+                        itemId: 'deliverGrids',
+                        text: 'Deliver Grids',
+                    },
                   ]
                 }, {
                   xtype: 'panel',
                   title: 'Widgets',
-                  itemId: 'contour_edit',
-                  style: {fontFamily: '"Inconsolata", monospace'},
+                  itemId: 'widget_edit',
                   layout: 'absolute',
                   flex: 1,
                   items : [
@@ -90,8 +96,7 @@
                 }, {
                   xtype: 'panel',
                   title: 'Camera Path',
-                  itemId: 'contour_edit',
-                  style: {fontFamily: '"Inconsolata", monospace'},
+                  itemId: 'camera_path',
                   layout: 'absolute',
                   flex: 1,
                   items : [


diff -r 4b8216200c3eb78638296ffe293106607b833529 -r 7e09c4f1b1e708ce3d7507e9096d8834daab3cd1 yt/gui/reason/html/resources/css/style.css
--- a/yt/gui/reason/html/resources/css/style.css
+++ b/yt/gui/reason/html/resources/css/style.css
@@ -74,4 +74,8 @@
 
 div.XTKscene {
     background-color:#000;
+    margin: 0;
+    padding: 0;
+    height: 100%;
+    overflow: hidden !important;
 }


diff -r 4b8216200c3eb78638296ffe293106607b833529 -r 7e09c4f1b1e708ce3d7507e9096d8834daab3cd1 yt/gui/reason/widget_builders.py
--- a/yt/gui/reason/widget_builders.py
+++ b/yt/gui/reason/widget_builders.py
@@ -76,9 +76,11 @@
 
 
 def get_corners(pf, max_level=None):
-    corners = (100*pf.h.grid_corners).tolist()
+    DL = pf.domain_left_edge[None,:,None]
+    DW = pf.domain_width[None,:,None]/100.0
+    corners = ((pf.h.grid_corners-DL)/DW).tolist()
     levels = pf.h.grid_levels.tolist()
-    return corners, levels    
+    return corners, levels
 
 def get_grid_vertices(pf, max_level=None):
     if max_level is None: max_level = pf.h.max_level



https://bitbucket.org/yt_analysis/yt/changeset/be5270b7ec93/
changeset:   be5270b7ec93
branch:      yt
user:        MatthewTurk
date:        2012-06-23 04:11:02
summary:     Adding grids by individual level
affected #:  2 files

diff -r 7e09c4f1b1e708ce3d7507e9096d8834daab3cd1 -r be5270b7ec93bb3179f35e0df9afd1503bb10ea2 yt/gui/reason/html/app/controller/widgets/Scene.js
--- a/yt/gui/reason/html/app/controller/widgets/Scene.js
+++ b/yt/gui/reason/html/app/controller/widgets/Scene.js
@@ -54,7 +54,8 @@
 
     applyPayload: function(payload) {
         if (payload['ptype'] == 'grid_lines') {
-            this.addGridLines(payload['corners'], payload['levels']);
+            this.addGridLines(payload['corners'], payload['levels'],
+                              payload['max_level']);
         } else {
             console.log("Unknown payload type received for 3D scene: " +
                         payload['ptype']);
@@ -93,20 +94,25 @@
         this.renderer = new X.renderer3D();
         this.renderer.container = toRender;
         this.renderer.init();
+        /*this.renderer.interactor.onKey = function() {};*/
+        examine = this.renderer;
     },
 
-    addGridLines: function(corners, levels) {
-        var grids = new X.mesh();
-        this.widgets.push(grids);
-        grids.ga = "LINES";
-        var p = grids.points;
-        var n = grids.normals;
-        var ii = 0;
-        var i;
+    addGridLines: function(corners, levels, maxLevel) {
+        var i, g, n, p;
         var order1 = [0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3];
         var order2 = [1, 2, 3, 0, 5, 6, 7, 4, 4, 5, 6, 7];
-        examine = corners;
+        gw = [];
+        for (i = 0; i < maxLevel + 1; i = i + 1) {
+            var grids = new X.mesh();
+            grids.name = "Grid Level " + i;
+            gw.push(grids);
+            this.widgets.push(grids);
+            grids.ga = "LINES";
+        }
         Ext.each(levels, function(level, index, allLevels) {
+            p = gw[level].points;
+            n = gw[level].normals;
             for (i = 0; i < 12; i = i + 1) {
                 n.add(1.0, 0.0, 0.0);
                 n.add(1.0, 0.0, 0.0);
@@ -118,7 +124,9 @@
                       corners[order2[i]][2][index]);
             }
         });
-        this.renderer.add(grids);
+        for (i = 0; i < maxLevel + 1; i = i + 1) {
+            this.renderer.add(gw[i]);
+        }
         this.renderer.render();
     }
 


diff -r 7e09c4f1b1e708ce3d7507e9096d8834daab3cd1 -r be5270b7ec93bb3179f35e0df9afd1503bb10ea2 yt/gui/reason/widget_store.py
--- a/yt/gui/reason/widget_store.py
+++ b/yt/gui/reason/widget_store.py
@@ -234,7 +234,8 @@
         corners, levels = get_corners(self.pf)
         ph.widget_payload(self, {'ptype':'grid_lines',
                                  'corners': corners,
-                                 'levels': levels})
+                                 'levels': levels,
+                                 'max_level': int(self.pf.h.max_level)})
         return
 
     def deliver_streamlines(self):



https://bitbucket.org/yt_analysis/yt/changeset/e676a4759c8d/
changeset:   e676a4759c8d
branch:      yt
user:        MatthewTurk
date:        2012-06-23 05:30:23
summary:     Initial import of the camera path editor.
affected #:  3 files

diff -r be5270b7ec93bb3179f35e0df9afd1503bb10ea2 -r e676a4759c8da1a7839779b759874461b5f99688 yt/gui/reason/html/app/controller/widgets/Scene.js
--- a/yt/gui/reason/html/app/controller/widgets/Scene.js
+++ b/yt/gui/reason/html/app/controller/widgets/Scene.js
@@ -27,7 +27,8 @@
 
 Ext.define("Reason.controller.widgets.Scene", {
     extend: 'Reason.controller.widgets.BaseWidget',
-    requires: ['Reason.view.widgets.Scene'],
+    requires: ['Reason.view.widgets.Scene',
+               'Reason.store.widgets.CameraKeyFrames'],
     templates: {
         createScene: 'widget_store.create_scene({varname})',
         deliverGrids: 'widget_store["{widget.varname}"].deliver_gridlines()',
@@ -36,22 +37,24 @@
     /* These call functions on the controller object */
     widgetTriggers: [
         ["#scenepanel", "afterrender", "setupXTK"],
+        ["#addKeyframe", "click", "addKeyframe"],
     ],
 
     /* These call templates */
     executionTriggers: [
-        ["#deliverGrids", "click", "deliverGrids"],
     ],
 
     /* ref: and selector: */
     viewRefs: [
         { ref:'scenePanel', selector: '#scenepanel' },
+        { ref:'keyFrameView', selector: '#keyframeview' },
     ],
 
     /* key: , shift: and tpl: */
     keyTriggers: [
     ],
 
+
     applyPayload: function(payload) {
         if (payload['ptype'] == 'grid_lines') {
             this.addGridLines(payload['corners'], payload['levels'],
@@ -71,6 +74,8 @@
         this.createMyRefs(this.dataView.id);
         this.applyExecuteHandlers(this.dataView);
         this.widgets = [];
+        this.keyFrames = Ext.create("Reason.store.widgets.CameraKeyFrames");
+        this.getKeyFrameView().bindStore(this.keyFrames);
         return this.dataView;
     },
 
@@ -94,8 +99,11 @@
         this.renderer = new X.renderer3D();
         this.renderer.container = toRender;
         this.renderer.init();
-        /*this.renderer.interactor.onKey = function() {};*/
-        examine = this.renderer;
+        this.renderer.interactor.config.KEYBOARD_ENABLED = false;
+        this.renderer.interactor.init();
+        var cmd = this.templateManager.applyObject(
+            {widget: this.dataView}, 'deliverGrids');
+        reason.server.execute(cmd);
     },
 
     addGridLines: function(corners, levels, maxLevel) {
@@ -128,6 +136,18 @@
             this.renderer.add(gw[i]);
         }
         this.renderer.render();
-    }
+    },
+
+    addKeyframe: function() {
+        var v = this.renderer.camera.view.toArray();
+        examine = v;
+        this.keyFrames.add({
+            time: 1.0,
+            view: v,
+            pos_x: -v[0][3],
+            pos_y: -v[1][3],
+            pos_z: -v[2][3],
+        });
+    },
 
 });


diff -r be5270b7ec93bb3179f35e0df9afd1503bb10ea2 -r e676a4759c8da1a7839779b759874461b5f99688 yt/gui/reason/html/app/store/widgets/CameraKeyFrames.js
--- /dev/null
+++ b/yt/gui/reason/html/app/store/widgets/CameraKeyFrames.js
@@ -0,0 +1,44 @@
+/**********************************************************************
+Camera Key Frame store for Reason
+
+Author: Cameron Hummels <chummels at gmail.com>
+Affiliation: Columbia
+Author: Jeffrey S. Oishi <jsoishi at gmail.com>
+Affiliation: KIPAC/SLAC/Stanford
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: MSU
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define('Reason.store.widgets.CameraKeyFrames', {
+    extend: 'Ext.data.Store',
+    id: 'camerakeyframes',
+    fields: [
+       {name: 'time', type:'float'},
+       {name: 'pos_x', type:'float'},
+       {name: 'pos_y', type:'float'},
+       {name: 'pos_z', type:'float'},
+       {name: 'view'},
+    ],
+    data: [],
+});
+


diff -r be5270b7ec93bb3179f35e0df9afd1503bb10ea2 -r e676a4759c8da1a7839779b759874461b5f99688 yt/gui/reason/html/app/view/widgets/Scene.js
--- a/yt/gui/reason/html/app/view/widgets/Scene.js
+++ b/yt/gui/reason/html/app/view/widgets/Scene.js
@@ -79,11 +79,6 @@
                   layout: 'absolute',
                   flex: 1,
                   items : [
-                    {
-                        xtype: 'button',
-                        itemId: 'deliverGrids',
-                        text: 'Deliver Grids',
-                    },
                   ]
                 }, {
                   xtype: 'panel',
@@ -97,9 +92,60 @@
                   xtype: 'panel',
                   title: 'Camera Path',
                   itemId: 'camera_path',
-                  layout: 'absolute',
-                  flex: 1,
+                  layout: {
+                    type: 'vbox',
+                    pack: 'start',
+                    align: 'stretch',
+                  },
+                  flex: 1.0,
                   items : [
+                    {
+                      xtype: 'gridpanel',
+                      flex: 1.0,
+                      selType: 'cellmodel',
+                      columns: [
+                        {
+                          id: 'time',
+                          header: 'Time',
+                          dataIndex: 'time',
+                          editor: {
+                            xtype: 'textfield',
+                          },
+                          flex: 1.0,
+                          sortable: true,
+                        }, {
+                          id: 'pos_x',
+                          header: 'Pos X',
+                          dataIndex: 'pos_x',
+                          editor: false,
+                          flex: 1.0,
+                          sortable: true,
+                        }, {
+                          id: 'pos_y',
+                          header: 'Pos Y',
+                          dataIndex: 'pos_y',
+                          editor: false,
+                          flex: 1.0,
+                          sortable: true,
+                        }, {
+                          id: 'pos_z',
+                          header: 'Pos Z',
+                          dataIndex: 'pos_z',
+                          editor: false,
+                          flex: 1.0,
+                          sortable: true,
+                        },
+                      ],
+                      itemId: 'keyframeview',
+                      plugins: [
+                        {ptype: 'cellediting',
+                         clicksToEdit: 1},
+                      ],
+                    }, {
+                      xtype: 'button',
+                      text: 'Add Keyframe',
+                      itemId: 'addKeyframe',
+                    }
                   ]
                 }
                 ] } /* tabpanel items and entry */



https://bitbucket.org/yt_analysis/yt/changeset/224852bf3a05/
changeset:   224852bf3a05
branch:      yt
user:        MatthewTurk
date:        2012-06-23 05:58:11
summary:     Clicking on a row in the camera path goes to that view.
affected #:  2 files

diff -r e676a4759c8da1a7839779b759874461b5f99688 -r 224852bf3a05e3a5e7d9b812b5c992645089b90a yt/gui/reason/html/app/controller/widgets/Scene.js
--- a/yt/gui/reason/html/app/controller/widgets/Scene.js
+++ b/yt/gui/reason/html/app/controller/widgets/Scene.js
@@ -38,6 +38,7 @@
     widgetTriggers: [
         ["#scenepanel", "afterrender", "setupXTK"],
         ["#addKeyframe", "click", "addKeyframe"],
+        ["#keyframeview", "select", "shiftToKeyframe"],
     ],
 
     /* These call templates */
@@ -139,15 +140,20 @@
     },
 
     addKeyframe: function() {
-        var v = this.renderer.camera.view.toArray();
-        examine = v;
+        var v = this.renderer.camera.view;
+        var va = v.toArray();
         this.keyFrames.add({
             time: 1.0,
             view: v,
-            pos_x: -v[0][3],
-            pos_y: -v[1][3],
-            pos_z: -v[2][3],
+            pos_x: -va[0][3],
+            pos_y: -va[1][3],
+            pos_z: -va[2][3],
         });
     },
 
+    shiftToKeyframe: function(rowModel, record, index) {
+        this.renderer.camera.view = record.data.view;
+        this.renderer.render();
+    },
+
 });


diff -r e676a4759c8da1a7839779b759874461b5f99688 -r 224852bf3a05e3a5e7d9b812b5c992645089b90a yt/gui/reason/html/app/view/widgets/Scene.js
--- a/yt/gui/reason/html/app/view/widgets/Scene.js
+++ b/yt/gui/reason/html/app/view/widgets/Scene.js
@@ -101,8 +101,9 @@
                   items : [
                     {
                       xtype: 'gridpanel',
+                      itemId: 'keyframeview',
                       flex: 1.0,
-                      selType: 'cellmodel',
+                      selType: 'rowmodel',
                       columns: [
                         {
                           id: 'time',
@@ -136,7 +137,6 @@
                           sortable: true,
                         },
                       ],
-                      itemId: 'keyframeview',
                       plugins: [
                         {ptype: 'cellediting',
                          clicksToEdit: 1},



https://bitbucket.org/yt_analysis/yt/changeset/2eee86ecf00e/
changeset:   2eee86ecf00e
branch:      yt
user:        MatthewTurk
date:        2012-06-23 16:32:08
summary:     Widgets are added to the checkbox list, and can be toggled in the 3D scene.
affected #:  8 files

diff -r 224852bf3a05e3a5e7d9b812b5c992645089b90a -r 2eee86ecf00e00f22d286e6c4ccb22ade30bd50b yt/gui/reason/html/app/controller/widgets/Scene.js
--- a/yt/gui/reason/html/app/controller/widgets/Scene.js
+++ b/yt/gui/reason/html/app/controller/widgets/Scene.js
@@ -28,7 +28,9 @@
 Ext.define("Reason.controller.widgets.Scene", {
     extend: 'Reason.controller.widgets.BaseWidget',
     requires: ['Reason.view.widgets.Scene',
-               'Reason.store.widgets.CameraKeyFrames'],
+               'Reason.store.widgets.CameraKeyFrames',
+               'Reason.store.widgets.SceneWidgets',
+               'Ext.ux.CheckColumn'],
     templates: {
         createScene: 'widget_store.create_scene({varname})',
         deliverGrids: 'widget_store["{widget.varname}"].deliver_gridlines()',
@@ -39,6 +41,7 @@
         ["#scenepanel", "afterrender", "setupXTK"],
         ["#addKeyframe", "click", "addKeyframe"],
         ["#keyframeview", "select", "shiftToKeyframe"],
+        ["#widgetEnabled", "checkchange", "toggleWidgetEnabled"],
     ],
 
     /* These call templates */
@@ -49,6 +52,7 @@
     viewRefs: [
         { ref:'scenePanel', selector: '#scenepanel' },
         { ref:'keyFrameView', selector: '#keyframeview' },
+        { ref:'widgetPanel', selector: '#widgetlist'},
     ],
 
     /* key: , shift: and tpl: */
@@ -74,9 +78,10 @@
         });
         this.createMyRefs(this.dataView.id);
         this.applyExecuteHandlers(this.dataView);
-        this.widgets = [];
         this.keyFrames = Ext.create("Reason.store.widgets.CameraKeyFrames");
         this.getKeyFrameView().bindStore(this.keyFrames);
+        this.widgets = Ext.create("Reason.store.widgets.SceneWidgets");
+        this.getWidgetPanel().bindStore(this.widgets);
         return this.dataView;
     },
 
@@ -114,9 +119,13 @@
         gw = [];
         for (i = 0; i < maxLevel + 1; i = i + 1) {
             var grids = new X.mesh();
-            grids.name = "Grid Level " + i;
             gw.push(grids);
-            this.widgets.push(grids);
+            this.widgets.add({
+              name: "Grid Level " + i,
+              type: 'grids',
+              widget: grids,
+              enabled: true,
+            });
             grids.ga = "LINES";
         }
         Ext.each(levels, function(level, index, allLevels) {
@@ -156,4 +165,11 @@
         this.renderer.render();
     },
 
+    toggleWidgetEnabled: function(column, rowIndex, enabled) {
+        /* We have to get the store, then the widget ... */
+        var rec = this.widgets.data.items[rowIndex];
+        rec.data.widget.visible = enabled;
+        this.renderer.render();
+    },
+
 });


diff -r 224852bf3a05e3a5e7d9b812b5c992645089b90a -r 2eee86ecf00e00f22d286e6c4ccb22ade30bd50b yt/gui/reason/html/app/store/widgets/SceneWidgets.js
--- /dev/null
+++ b/yt/gui/reason/html/app/store/widgets/SceneWidgets.js
@@ -0,0 +1,36 @@
+/**********************************************************************
+Widget Store for Reason
+
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2012 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define('Reason.store.widgets.SceneWidgets', {
+    extend: 'Ext.data.Store',
+    id: 'scenewidgets',
+    fields: [
+       {name: 'name', type: 'string'},
+       {name: 'enabled', type: 'boolean', defaultValue: true},
+       {name: 'type', type: 'string'},
+       {name: 'widget'},
+    ],
+    data: [],
+});


diff -r 224852bf3a05e3a5e7d9b812b5c992645089b90a -r 2eee86ecf00e00f22d286e6c4ccb22ade30bd50b yt/gui/reason/html/app/view/widgets/Scene.js
--- a/yt/gui/reason/html/app/view/widgets/Scene.js
+++ b/yt/gui/reason/html/app/view/widgets/Scene.js
@@ -74,19 +74,44 @@
                   items: [
                 {
                   xtype: 'panel',
-                  title: 'Data Editor',
-                  itemId: 'data_edit',
-                  layout: 'absolute',
-                  flex: 1,
-                  items : [
-                  ]
-                }, {
-                  xtype: 'panel',
                   title: 'Widgets',
                   itemId: 'widget_edit',
-                  layout: 'absolute',
                   flex: 1,
+                  layout: {
+                    type: 'vbox',
+                    pack: 'start',
+                    align: 'stretch',
+                  },
                   items : [
+                    {
+                      xtype: 'gridpanel',
+                      itemId: 'widgetlist',
+                      flex: 1.0,
+                      selType: 'rowmodel',
+                      columns: [
+                        {
+                          itemId: 'widgetEnabled',
+                          header: '',
+                          dataIndex: 'enabled',
+                          xtype: 'checkcolumn',
+                          width: 30,
+                        }, {
+                          itemId: 'name',
+                          header: 'Name',
+                          dataIndex: 'name',
+                          editor: false,
+                        }, {
+                          itemId: 'type',
+                          header: 'Type',
+                          dataIndex: 'type',
+                          editor: false,
+                        }
+                      ],
+                      plugins: [
+                        {ptype: 'cellediting',
+                         clicksToEdit: 1},
+                      ],
+                    },
                   ]
                 }, {
                   xtype: 'panel',
@@ -147,7 +172,15 @@
                       itemId: 'addKeyframe',
                     }
                   ]
-                }
+                }, {
+                  xtype: 'panel',
+                  title: 'Data Editor',
+                  itemId: 'data_edit',
+                  layout: 'absolute',
+                  flex: 1,
+                  items : [
+                  ]
+                },
                 ] } /* tabpanel items and entry */
                 ]
         }


diff -r 224852bf3a05e3a5e7d9b812b5c992645089b90a -r 2eee86ecf00e00f22d286e6c4ccb22ade30bd50b yt/gui/reason/html/index.html
--- a/yt/gui/reason/html/index.html
+++ b/yt/gui/reason/html/index.html
@@ -10,6 +10,7 @@
     <!-- LIBS --><link rel="stylesheet" type="text/css" href="resources/extjs-4.1.0/resources/css/ext-all-gray.css"><link rel="stylesheet" type="text/css" href="reason/resources/css/style.css">
+    <link rel="stylesheet" type="text/css" href="reason/resources/css/CheckHeader.css"><link rel="stylesheet" type="text/css" href="highlighter.css"><script type="text/javascript" src="resources/extjs-4.1.0/ext-all-debug.js"></script>
@@ -17,6 +18,9 @@
     <script type="text/javascript" src="ext-repl-api.js"></script><script type="text/javascript" src="resources/ext-pflist-api.js"></script>
 
+    <!-- Additional Ext UX files -->
+    <script type="text/javascript" src="reason/resources/ux/CheckColumn.js"></script>
+
     <!-- LEAFLET STUFF --><script type="text/javascript" src="reason/resources/leaflet/leaflet.js"></script><link rel="stylesheet" href="reason/resources/leaflet/leaflet.css" />


diff -r 224852bf3a05e3a5e7d9b812b5c992645089b90a -r 2eee86ecf00e00f22d286e6c4ccb22ade30bd50b yt/gui/reason/html/resources/css/CheckHeader.css
--- /dev/null
+++ b/yt/gui/reason/html/resources/css/CheckHeader.css
@@ -0,0 +1,23 @@
+.x-grid-cell-checkcolumn .x-grid-cell-inner {
+    padding-top: 4px;
+    padding-bottom: 2px;
+    line-height: 14px;
+}
+.x-grid-with-row-lines .x-grid-cell-checkcolumn .x-grid-cell-inner {
+    padding-top: 3px;
+}
+.x-grid-checkheader {
+    height: 14px;
+    background-image: url('images/unchecked.gif');
+    background-position: 50% -2px;
+    background-repeat: no-repeat;
+    background-color: transparent;
+}
+
+.x-grid-checkheader-checked {
+    background-image: url('images/checked.gif');
+}
+
+.x-grid-checkheader-editor .x-form-cb-wrap {
+    text-align: center;
+}


diff -r 224852bf3a05e3a5e7d9b812b5c992645089b90a -r 2eee86ecf00e00f22d286e6c4ccb22ade30bd50b yt/gui/reason/html/resources/css/images/checked.gif
Binary file yt/gui/reason/html/resources/css/images/checked.gif has changed


diff -r 224852bf3a05e3a5e7d9b812b5c992645089b90a -r 2eee86ecf00e00f22d286e6c4ccb22ade30bd50b yt/gui/reason/html/resources/css/images/unchecked.gif
Binary file yt/gui/reason/html/resources/css/images/unchecked.gif has changed


diff -r 224852bf3a05e3a5e7d9b812b5c992645089b90a -r 2eee86ecf00e00f22d286e6c4ccb22ade30bd50b yt/gui/reason/html/resources/ux/CheckColumn.js
--- /dev/null
+++ b/yt/gui/reason/html/resources/ux/CheckColumn.js
@@ -0,0 +1,118 @@
+/**
+ * @class Ext.ux.CheckColumn
+ * @extends Ext.grid.column.Column
+ * A Header subclass which renders a checkbox in each column cell which toggles the truthiness of the associated data field on click.
+ *
+ * Example usage:
+ * 
+ *    // create the grid
+ *    var grid = Ext.create('Ext.grid.Panel', {
+ *        ...
+ *        columns: [{
+ *           text: 'Foo',
+ *           ...
+ *        },{
+ *           xtype: 'checkcolumn',
+ *           text: 'Indoor?',
+ *           dataIndex: 'indoor',
+ *           width: 55
+ *        }]
+ *        ...
+ *    });
+ *
+ * In addition to toggling a Boolean value within the record data, this
+ * class adds or removes a css class <tt>'x-grid-checked'</tt> on the td
+ * based on whether or not it is checked to alter the background image used
+ * for a column.
+ */
+Ext.define('Ext.ux.CheckColumn', {
+    extend: 'Ext.grid.column.Column',
+    alias: 'widget.checkcolumn',
+
+    /**
+     * @cfg {Boolean} [stopSelection=true]
+     * Prevent grid selection upon mousedown.
+     */
+    stopSelection: true,
+
+    tdCls: Ext.baseCSSPrefix + 'grid-cell-checkcolumn',
+
+    constructor: function() {
+        this.addEvents(
+            /**
+             * @event beforecheckchange
+             * Fires when before checked state of a row changes.
+             * The change may be vetoed by returning `false` from a listener.
+             * @param {Ext.ux.CheckColumn} this CheckColumn
+             * @param {Number} rowIndex The row index
+             * @param {Boolean} checked True if the box is to be checked
+             */
+            'beforecheckchange',
+            /**
+             * @event checkchange
+             * Fires when the checked state of a row changes
+             * @param {Ext.ux.CheckColumn} this CheckColumn
+             * @param {Number} rowIndex The row index
+             * @param {Boolean} checked True if the box is now checked
+             */
+            'checkchange'
+        );
+        this.callParent(arguments);
+    },
+
+    /**
+     * @private
+     * Process and refire events routed from the GridView's processEvent method.
+     */
+    processEvent: function(type, view, cell, recordIndex, cellIndex, e) {
+        var me = this,
+            key = type === 'keydown' && e.getKey(),
+            mousedown = type == 'mousedown';
+
+        if (mousedown || (key == e.ENTER || key == e.SPACE)) {
+            var record = view.panel.store.getAt(recordIndex),
+                dataIndex = me.dataIndex,
+                checked = !record.get(dataIndex);
+
+            // Allow apps to hook beforecheckchange
+            if (me.fireEvent('beforecheckchange', me, recordIndex, checked) !== false) {
+                record.set(dataIndex, checked);
+                me.fireEvent('checkchange', me, recordIndex, checked);
+
+                // Mousedown on the now nonexistent cell causes the view to blur, so stop it continuing.
+                if (mousedown) {
+                    e.stopEvent();
+                }
+
+                // Selection will not proceed after this because of the DOM update caused by the record modification
+                // Invoke the SelectionModel unless configured not to do so
+                if (!me.stopSelection) {
+                    view.selModel.selectByPosition({
+                        row: recordIndex,
+                        column: cellIndex
+                    });
+                }
+
+                // Prevent the view from propagating the event to the selection model - we have done that job.
+                return false;
+            } else {
+                // Prevent the view from propagating the event to the selection model if configured to do so.
+                return !me.stopSelection;
+            }
+        } else {
+            return me.callParent(arguments);
+        }
+    },
+
+    // Note: class names are not placed on the prototype bc renderer scope
+    // is not in the header.
+    renderer : function(value){
+        var cssPrefix = Ext.baseCSSPrefix,
+            cls = [cssPrefix + 'grid-checkheader'];
+
+        if (value) {
+            cls.push(cssPrefix + 'grid-checkheader-checked');
+        }
+        return '<div class="' + cls.join(' ') + '"> </div>';
+    }
+});



https://bitbucket.org/yt_analysis/yt/changeset/4254f7b9d2c2/
changeset:   4254f7b9d2c2
branch:      yt
user:        MatthewTurk
date:        2012-06-23 16:59:52
summary:     Initial passing of camera path to the server / scene widget.
affected #:  2 files

diff -r 2eee86ecf00e00f22d286e6c4ccb22ade30bd50b -r 4254f7b9d2c292399a807e9644fa2ca82c95a997 yt/gui/reason/html/app/controller/widgets/Scene.js
--- a/yt/gui/reason/html/app/controller/widgets/Scene.js
+++ b/yt/gui/reason/html/app/controller/widgets/Scene.js
@@ -40,6 +40,7 @@
     widgetTriggers: [
         ["#scenepanel", "afterrender", "setupXTK"],
         ["#addKeyframe", "click", "addKeyframe"],
+        ["#renderPath", "click", "renderPath"],
         ["#keyframeview", "select", "shiftToKeyframe"],
         ["#widgetEnabled", "checkchange", "toggleWidgetEnabled"],
     ],
@@ -172,4 +173,21 @@
         this.renderer.render();
     },
 
+    renderPath: function() {
+        
+        var t = new Ext.XTemplate("[[{0}, {1}, {2}, {3}], ",
+                                  " [{4}, {5}, {6}, {7}], ",
+                                  " [{8}, {9}, {10}, {11}], ",
+                                  " [{12}, {13}, {14}, {15}]],\n");
+        var cmdt = new Ext.XTemplate("widget_store['{0}'].render_path(\n",
+                                     "[{1}]\n,[{2}], 100)");
+        var path = "";
+        var times = "";
+        Ext.each(this.keyFrames.data.items, function(rec, ind, all) {
+            times = times + rec.data.time + ", ";
+            path = path + t.apply(rec.data.view.flatten());
+        });
+        var cmd = cmdt.apply([this.dataView.varname, path, times]);
+    },
+
 });


diff -r 2eee86ecf00e00f22d286e6c4ccb22ade30bd50b -r 4254f7b9d2c292399a807e9644fa2ca82c95a997 yt/gui/reason/html/app/view/widgets/Scene.js
--- a/yt/gui/reason/html/app/view/widgets/Scene.js
+++ b/yt/gui/reason/html/app/view/widgets/Scene.js
@@ -170,6 +170,10 @@
                       xtype: 'button',
                       text: 'Add Keyframe',
                       itemId: 'addKeyframe',
+                    }, {
+                      xtype: 'button',
+                      text: 'Render Path',
+                      itemId: 'renderPath',
                     }
                   ]
                 }, {



https://bitbucket.org/yt_analysis/yt/changeset/3f7db9fadf54/
changeset:   3f7db9fadf54
branch:      yt
user:        MatthewTurk
date:        2012-06-23 18:03:10
summary:     Merging from tip
affected #:  127 files
Diff too large to display.

https://bitbucket.org/yt_analysis/yt/changeset/38c0540666f0/
changeset:   38c0540666f0
branch:      yt
user:        MatthewTurk
date:        2012-06-23 18:12:03
summary:     Typo change to diverge bookmarks
affected #:  1 file

diff -r 3f7db9fadf542dab187e827ca91acf9211b1463d -r 38c0540666f0c1013bf3e82678141360a644c6db yt/gui/reason/html/app/view/widgets/Scene.js
--- a/yt/gui/reason/html/app/view/widgets/Scene.js
+++ b/yt/gui/reason/html/app/view/widgets/Scene.js
@@ -172,7 +172,7 @@
                       itemId: 'addKeyframe',
                     }, {
                       xtype: 'button',
-                      text: 'Render Path',
+                      text: 'Calculate Path',
                       itemId: 'renderPath',
                     }
                   ]



https://bitbucket.org/yt_analysis/yt/changeset/607b7df49072/
changeset:   607b7df49072
branch:      yt
user:        MatthewTurk
date:        2012-06-23 19:03:56
summary:     Isocontours can now be added to a 3D scene, although the current way of doing
it is a bit memory-intensive on both the server and the client.
affected #:  4 files

diff -r 38c0540666f0c1013bf3e82678141360a644c6db -r 607b7df490721bf8106e8b556bb345cd1200b27f yt/gui/reason/html/app/controller/widgets/Scene.js
--- a/yt/gui/reason/html/app/controller/widgets/Scene.js
+++ b/yt/gui/reason/html/app/controller/widgets/Scene.js
@@ -34,6 +34,7 @@
     templates: {
         createScene: 'widget_store.create_scene({varname})',
         deliverGrids: 'widget_store["{widget.varname}"].deliver_gridlines()',
+        createIsocontour: 'widget_store["{widget.varname}"].deliver_isocontour("Density", None)',
     },
 
     /* These call functions on the controller object */
@@ -47,6 +48,7 @@
 
     /* These call templates */
     executionTriggers: [
+        ["#addIsocontour", "click", "createIsocontour"],
     ],
 
     /* ref: and selector: */
@@ -65,6 +67,8 @@
         if (payload['ptype'] == 'grid_lines') {
             this.addGridLines(payload['corners'], payload['levels'],
                               payload['max_level']);
+        } else if (payload['ptype'] == 'isocontour') {
+            this.addIsocontour(payload['vert'], payload['normals']);
         } else {
             console.log("Unknown payload type received for 3D scene: " +
                         payload['ptype']);
@@ -149,6 +153,44 @@
         this.renderer.render();
     },
 
+    addIsocontour: function(vertices, normals) {
+        alert("Adding isocontours.");
+        var i, g, n, p;
+        Ext.MessageBox.show({
+            title : "Adding Isocontour Vertices",
+            width: 300,
+            msg: "Updating ...",
+            progress: true,
+            closable: false,
+        });
+        var nv = vertices.length();
+        var last = 0;
+        var surf = new X.mesh();
+        this.widgets.add({
+          name: "Isocontour",
+          type: 'isocontour',
+          widget: surf,
+          enabled: true,
+        });
+        surf.ga = "TRIANGLES";
+        p = surf.points;
+        n = surf.normals;
+        Ext.each(vertices, function(vert, index, allVerts) {
+            if ((index - last) > ( nv / 100.0)) {
+                Ext.MessageBox.updateProgress(
+                        (index / nv),
+                        Math.round(100*index/nv) + '% completed');
+                last = index;
+            }
+            p.add(vert[0], vert[1], vert[2]);
+            n.add(normals[index][0], normals[index][1], normals[index][2]);
+        });
+        Ext.MessageBox.hide();
+        surf.color = [1.0, 0.0, 0.0];
+        this.renderer.add(surf);
+        this.renderer.render();
+    },
+
     addKeyframe: function() {
         var v = this.renderer.camera.view;
         var va = v.toArray();


diff -r 38c0540666f0c1013bf3e82678141360a644c6db -r 607b7df490721bf8106e8b556bb345cd1200b27f yt/gui/reason/html/app/view/widgets/Scene.js
--- a/yt/gui/reason/html/app/view/widgets/Scene.js
+++ b/yt/gui/reason/html/app/view/widgets/Scene.js
@@ -183,6 +183,11 @@
                   layout: 'absolute',
                   flex: 1,
                   items : [
+                    {
+                      xtype: 'button',
+                      text: 'Add Isocontour',
+                      itemId: 'addIsocontour'
+                    },
                   ]
                 },
                 ] } /* tabpanel items and entry */


diff -r 38c0540666f0c1013bf3e82678141360a644c6db -r 607b7df490721bf8106e8b556bb345cd1200b27f yt/gui/reason/widget_builders.py
--- a/yt/gui/reason/widget_builders.py
+++ b/yt/gui/reason/widget_builders.py
@@ -82,40 +82,6 @@
     levels = pf.h.grid_levels.tolist()
     return corners, levels
 
-def get_grid_vertices(pf, max_level=None):
-    if max_level is None: max_level = pf.h.max_level
-    fns = []
-    for lvl in range(max_level):
-        fn = "%s_lvl_%02i_grids.vtk"%(pf, lvl)
-        f = open(fn, "w")
-
-        f.write("""# vtk DataFile Version 3.0
-        vtk output
-        ASCII
-        DATASET POLYDATA
-        POINTS %s float
-        """ % (pf.h.num_grids * 8))
-
-        for gi in xrange(pf.h.num_grids):
-            if pf.h.grid_levels[gi][0] != lvl: continue
-            gc = pf.h.grid_corners[:, :, gi] * 100.0
-            for i in range(8):
-                f.write("%0.9f %0.9f %0.9f\n" % (gc[i, 0], gc[i, 1], gc[i, 2]))
-
-        f.write("LINES %s %s\n" % (pf.h.num_grids * 12, 3 * pf.h.num_grids * 12))
-
-        order1 = (0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3)
-        order2 = (1, 2, 3, 0, 5, 6, 7, 4, 4, 5, 6, 7)
-
-        for gi in xrange(pf.h.num_grids):
-            if pf.h.grid_levels[gi][0] != lvl: continue
-            offset = 8 * gi
-            for p1, p2 in zip(order1, order2):
-                f.write("2 %s %s\n" % (p1 + offset, p2 + offset))
-        f.close()
-        fns.append(fn)
-    return fn
-
 def get_isocontour(pf, field, value=None):
 
     dd = pf.h.all_data()
@@ -124,17 +90,7 @@
         value = 10.**((mi + ma)/2.)
     vert = dd.extract_isocontours("Density", value)
     na.multiply(vert, 100, vert)
-
-    fn = "%s_surface.vtk" % pf
-    f = open(fn, "w")
-    f.write("vtk output\nASCII\nDATASET POLYDATA\nPOINTS %s float\n" % (vert.shape[0]))
-    for v in vert:
-        f.write("%0.14f %0.14f %0.14f\n" % (v[0], v[1], v[2]))
-    f.write("VERTICES %s %s\n" % (vert.shape[0]/3, vert.shape[0] + vert.shape[0]/3))
-    for i in range(vert.shape[0]/3):
-        f.write("3 %i %i %i\n" % (i*3, i*3+1, i*3+2))
-    f.close()
-    return fn
+    return vert
 
 def get_streamlines(pf):
     from yt.visualization.api import Streamlines


diff -r 38c0540666f0c1013bf3e82678141360a644c6db -r 607b7df490721bf8106e8b556bb345cd1200b27f yt/gui/reason/widget_store.py
--- a/yt/gui/reason/widget_store.py
+++ b/yt/gui/reason/widget_store.py
@@ -26,7 +26,7 @@
 from yt.mods import *
 import weakref
 from .bottle_mods import PayloadHandler, lockit
-from .widget_builders import RenderingScene, get_corners
+from .widget_builders import RenderingScene, get_corners, get_isocontour
 from yt.visualization.plot_window import PWViewerExtJS
 import uuid
 
@@ -229,6 +229,17 @@
                                  'image':self._rendering_scene.snapshot()})
         return
 
+    def deliver_isocontour(self, field, value):
+        ph = PayloadHandler()
+        vert = get_isocontour(self.pf, field, value)
+        normals = na.empty(vert.shape)
+        for i in xrange(vert.shape[0]/3):
+            n = na.cross(vert[i*3,:], vert[i*3+1,:])
+            normals[i*3:i*3+3,:] = n[None,:]
+        ph.widget_payload(self, {'ptype':'isocontour',
+                                 'vert':vert.tolist(),
+                                 'normals':normals.tolist()})
+
     def deliver_gridlines(self):
         ph = PayloadHandler()
         corners, levels = get_corners(self.pf)



https://bitbucket.org/yt_analysis/yt/changeset/1eb0694ceafb/
changeset:   1eb0694ceafb
branch:      yt
user:        MatthewTurk
date:        2012-06-23 19:54:01
summary:     Bug fix for isocontours.
affected #:  2 files

diff -r 607b7df490721bf8106e8b556bb345cd1200b27f -r 1eb0694ceafbf5adfb79dfeda174cb0e16d24e98 yt/gui/reason/html/app/controller/widgets/Scene.js
--- a/yt/gui/reason/html/app/controller/widgets/Scene.js
+++ b/yt/gui/reason/html/app/controller/widgets/Scene.js
@@ -154,7 +154,7 @@
     },
 
     addIsocontour: function(vertices, normals) {
-        alert("Adding isocontours.");
+        console.log("Adding isocontours ...");
         var i, g, n, p;
         Ext.MessageBox.show({
             title : "Adding Isocontour Vertices",
@@ -163,7 +163,7 @@
             progress: true,
             closable: false,
         });
-        var nv = vertices.length();
+        var nv = vertices.length;
         var last = 0;
         var surf = new X.mesh();
         this.widgets.add({


diff -r 607b7df490721bf8106e8b556bb345cd1200b27f -r 1eb0694ceafbf5adfb79dfeda174cb0e16d24e98 yt/gui/reason/widget_builders.py
--- a/yt/gui/reason/widget_builders.py
+++ b/yt/gui/reason/widget_builders.py
@@ -87,7 +87,7 @@
     dd = pf.h.all_data()
     if value is None:
         mi, ma = na.log10(dd.quantities["Extrema"]("Density")[0])
-        value = 10.**((mi + ma)/2.)
+        value = 10.0**(0.75*(mi + ma))
     vert = dd.extract_isocontours("Density", value)
     na.multiply(vert, 100, vert)
     return vert



https://bitbucket.org/yt_analysis/yt/changeset/111f4fa253f5/
changeset:   111f4fa253f5
branch:      yt
user:        brittonsmith
date:        2012-06-23 20:39:16
summary:     Payload delivery now works with the Pyro4 server.
affected #:  1 file

diff -r 38c0540666f0c1013bf3e82678141360a644c6db -r 111f4fa253f550d75a11d6351ba1be96a65ac6b5 yt/gui/reason/extdirect_repl.py
--- a/yt/gui/reason/extdirect_repl.py
+++ b/yt/gui/reason/extdirect_repl.py
@@ -40,6 +40,7 @@
 import base64
 import imp
 import threading
+import Pyro4
 import Queue
 import zipfile
 
@@ -122,6 +123,45 @@
                  'raw_input': code},
                 )
 
+class PyroExecutionThread(ExecutionThread):
+    def __init__(self, repl):
+        ExecutionThread.__init__(self, repl)
+        hmac_key = raw_input("HMAC_KEY? ").strip()
+        uri = raw_input("URI? ").strip()
+        Pyro4.config.HMAC_KEY = hmac_key
+        self.executor = Pyro4.Proxy(uri)
+
+    def execute_one(self, code, hide):
+        self.repl.executed_cell_texts.append(code)
+        print code
+        result = self.executor.execute(code)
+        if not hide:
+            self.repl.payload_handler.add_payload(
+                {'type': 'cell',
+                 'output': result,
+                 'input': highlighter(code),
+                 'raw_input': code},
+                )
+        ph = self.executor.deliver()
+        for p in ph:
+            self.repl.payload_handler.add_payload(p)
+
+    def heartbeat(self):
+        self.last_heartbeat = time.time()
+        if self.debug: print "### Heartbeat ... started: %s" % (time.ctime())
+        for i in range(30):
+            # Check for stop
+            if self.debug: print "    ###"
+            if self.stopped: return {'type':'shutdown'} # No race condition
+            if self.payload_handler.event.wait(1): # One second timeout
+                if self.debug: print "    ### Delivering payloads"
+                rv = self.payload_handler.deliver_payloads()
+                if self.debug: print "    ### Got back, returning"
+                return rv
+        if self.debug: print "### Heartbeat ... finished: %s" % (time.ctime())
+        return []
+
+
 def deliver_image(im):
     if hasattr(im, 'read'):
         img_data = base64.b64encode(im.read())
@@ -205,7 +245,8 @@
         self.pflist = ExtDirectParameterFileList()
         self.executed_cell_texts = []
         self.payload_handler = PayloadHandler()
-        self.execution_thread = ExecutionThread(self)
+        #self.execution_thread = ExecutionThread(self)
+        self.execution_thread = PyroExecutionThread(self)
         # We pass in a reference to ourself
         self.widget_store = WidgetStore(self)
         # Now we load up all the yt.mods stuff, but only after we've finished



https://bitbucket.org/yt_analysis/yt/changeset/64a12a1140c1/
changeset:   64a12a1140c1
branch:      yt
user:        MatthewTurk
date:        2012-06-23 21:01:17
summary:     Isocontour creator.
affected #:  4 files

diff -r 1eb0694ceafbf5adfb79dfeda174cb0e16d24e98 -r 64a12a1140c10f3b7ec2d853dcbe5e6488d7266a yt/gui/reason/html/app/controller/widgets/Scene.js
--- a/yt/gui/reason/html/app/controller/widgets/Scene.js
+++ b/yt/gui/reason/html/app/controller/widgets/Scene.js
@@ -28,13 +28,15 @@
 Ext.define("Reason.controller.widgets.Scene", {
     extend: 'Reason.controller.widgets.BaseWidget',
     requires: ['Reason.view.widgets.Scene',
+               'Reason.view.widgets.IsocontourCreator',
                'Reason.store.widgets.CameraKeyFrames',
                'Reason.store.widgets.SceneWidgets',
                'Ext.ux.CheckColumn'],
     templates: {
         createScene: 'widget_store.create_scene({varname})',
         deliverGrids: 'widget_store["{widget.varname}"].deliver_gridlines()',
-        createIsocontour: 'widget_store["{widget.varname}"].deliver_isocontour("Density", None)',
+        createIsocontour: 'widget_store["{varname}"].deliver_isocontour(' +
+                          '"{field}", {value}, {relValue:capitalize})',
     },
 
     /* These call functions on the controller object */
@@ -44,11 +46,11 @@
         ["#renderPath", "click", "renderPath"],
         ["#keyframeview", "select", "shiftToKeyframe"],
         ["#widgetEnabled", "checkchange", "toggleWidgetEnabled"],
+        ["#addIsocontour", "click", "createIsocontour"],
     ],
 
     /* These call templates */
     executionTriggers: [
-        ["#addIsocontour", "click", "createIsocontour"],
     ],
 
     /* ref: and selector: */
@@ -62,7 +64,6 @@
     keyTriggers: [
     ],
 
-
     applyPayload: function(payload) {
         if (payload['ptype'] == 'grid_lines') {
             this.addGridLines(payload['corners'], payload['levels'],
@@ -87,6 +88,8 @@
         this.getKeyFrameView().bindStore(this.keyFrames);
         this.widgets = Ext.create("Reason.store.widgets.SceneWidgets");
         this.getWidgetPanel().bindStore(this.widgets);
+        this.fieldStore = Ext.create("Reason.store.Fields")
+        this.fieldStore.loadData(wd['fields']);
         return this.dataView;
     },
 
@@ -153,6 +156,29 @@
         this.renderer.render();
     },
 
+    createIsocontour: function() {
+        var win; 
+        var controller = this;
+        /* field , value */
+        function callExtract(b, e) {
+            var conf = {
+                varname: controller.dataView.varname,
+                field: win.query("#field")[0].getValue(),
+                value: win.query("#value")[0].getValue(),
+                relValue: "" + win.query("#relValue")[0].getValue(),
+            };
+            cmd = controller.templateManager.applyObject(
+                    conf, "createIsocontour");
+            reason.server.execute(cmd);
+            win.destroy();
+        }
+        win = Ext.widget("isocontourcreator");
+        win.query("#field")[0].bindStore(this.fieldStore);
+        win.query("#extract")[0].on('click', callExtract);
+        win.query("#cancel")[0].on('click', function(){win.destroy();});
+        win.show();
+    },
+
     addIsocontour: function(vertices, normals) {
         console.log("Adding isocontours ...");
         var i, g, n, p;


diff -r 1eb0694ceafbf5adfb79dfeda174cb0e16d24e98 -r 64a12a1140c10f3b7ec2d853dcbe5e6488d7266a yt/gui/reason/html/app/view/widgets/IsocontourCreator.js
--- /dev/null
+++ b/yt/gui/reason/html/app/view/widgets/IsocontourCreator.js
@@ -0,0 +1,77 @@
+/**********************************************************************
+The Isocontour Creator
+
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2012 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define("Reason.view.widgets.IsocontourCreator", {
+    extend: 'Ext.window.Window',
+    alias: 'widget.isocontourcreator',
+    width: 370,
+    height: 200,
+    modal: true,
+    resizable: false,
+    draggable: false,
+    border: false,
+    layout: 'fit',
+    title: "Create Phase Plot",
+
+    items: [{ xtype: 'form', // FormPanel
+              labelWidth:80,
+              frame:true,
+              items: [ {
+                xtype:'combo',
+                fieldLabel: 'Field',
+                id: 'field',
+                width: 290,
+                queryMode: 'local',
+                editable: false,
+                triggerAction: 'all',
+                value: 'Density'
+              },{
+                xtype:'checkboxfield',
+                fieldLabel: 'Relative Value?',
+                itemId: 'relValue',
+                value: true,
+                width: 290,
+                allowBlank:false,
+              },{
+                xtype:'textfield',
+                fieldLabel: 'Value',
+                itemId: 'value',
+                value: '0.5',
+                width: 290,
+                allowBlank:false,
+              }
+            ],
+            buttons: [
+                {
+                    text: 'Extract',
+                    itemId: 'extract',
+                },{
+                    text: 'Cancel',
+                    itemId: 'cancel',
+                }
+            ]
+        }],
+});
+


diff -r 1eb0694ceafbf5adfb79dfeda174cb0e16d24e98 -r 64a12a1140c10f3b7ec2d853dcbe5e6488d7266a yt/gui/reason/widget_builders.py
--- a/yt/gui/reason/widget_builders.py
+++ b/yt/gui/reason/widget_builders.py
@@ -82,12 +82,13 @@
     levels = pf.h.grid_levels.tolist()
     return corners, levels
 
-def get_isocontour(pf, field, value=None):
+def get_isocontour(pf, field, value=None, rel_val = False):
 
     dd = pf.h.all_data()
-    if value is None:
+    if value is None or rel_val:
+        if value is None: value = 0.5
         mi, ma = na.log10(dd.quantities["Extrema"]("Density")[0])
-        value = 10.0**(0.75*(mi + ma))
+        value = 10.0**(value*(mi + ma))
     vert = dd.extract_isocontours("Density", value)
     na.multiply(vert, 100, vert)
     return vert


diff -r 1eb0694ceafbf5adfb79dfeda174cb0e16d24e98 -r 64a12a1140c10f3b7ec2d853dcbe5e6488d7266a yt/gui/reason/widget_store.py
--- a/yt/gui/reason/widget_store.py
+++ b/yt/gui/reason/widget_store.py
@@ -163,7 +163,11 @@
     def create_scene(self, pf):
         '''Creates 3D XTK-based scene'''
         widget = SceneWidget(pf)
-        widget_data = {'title':'Scene for %s' % pf}
+        field_list = list(set(pf.h.field_list
+                            + pf.h.derived_field_list))
+        field_list.sort()
+        widget_data = {'title':'Scene for %s' % pf,
+                       'fields': field_list}
         self._add_widget(widget, widget_data)
 
 
@@ -229,9 +233,9 @@
                                  'image':self._rendering_scene.snapshot()})
         return
 
-    def deliver_isocontour(self, field, value):
+    def deliver_isocontour(self, field, value, rel_val = False):
         ph = PayloadHandler()
-        vert = get_isocontour(self.pf, field, value)
+        vert = get_isocontour(self.pf, field, value, rel_val)
         normals = na.empty(vert.shape)
         for i in xrange(vert.shape[0]/3):
             n = na.cross(vert[i*3,:], vert[i*3+1,:])



https://bitbucket.org/yt_analysis/yt/changeset/f95fdf428316/
changeset:   f95fdf428316
branch:      yt
user:        MatthewTurk
date:        2012-06-23 21:46:22
summary:      * Add progressbar for isocontour extraction
 * Have the keyframe rendering actually call the server.
affected #:  2 files

diff -r 64a12a1140c10f3b7ec2d853dcbe5e6488d7266a -r f95fdf42831691af785f85b45a48efbdfb729052 yt/data_objects/data_containers.py
--- a/yt/data_objects/data_containers.py
+++ b/yt/data_objects/data_containers.py
@@ -2634,13 +2634,16 @@
         """
         verts = []
         samples = []
+        pb = get_pbar("Extracting ", len(list(self._get_grid_objs())))
         for i, g in enumerate(self._get_grid_objs()):
+            pb.update(i)
             my_verts = self._extract_isocontours_from_grid(
                             g, field, value, sample_values)
             if sample_values is not None:
                 my_verts, svals = my_verts
                 samples.append(svals)
             verts.append(my_verts)
+        pb.finish()
         verts = na.concatenate(verts).transpose()
         verts = self.comm.par_combine_object(verts, op='cat', datatype='array')
         verts = verts.transpose()


diff -r 64a12a1140c10f3b7ec2d853dcbe5e6488d7266a -r f95fdf42831691af785f85b45a48efbdfb729052 yt/gui/reason/html/app/controller/widgets/Scene.js
--- a/yt/gui/reason/html/app/controller/widgets/Scene.js
+++ b/yt/gui/reason/html/app/controller/widgets/Scene.js
@@ -256,6 +256,7 @@
             path = path + t.apply(rec.data.view.flatten());
         });
         var cmd = cmdt.apply([this.dataView.varname, path, times]);
+        reason.server.execute(cmd);
     },
 
 });



https://bitbucket.org/yt_analysis/yt/changeset/b479296cc2c5/
changeset:   b479296cc2c5
branch:      yt
user:        MatthewTurk
date:        2012-06-23 22:10:14
summary:     Initial test of using binary payloads.
affected #:  3 files

diff -r f95fdf42831691af785f85b45a48efbdfb729052 -r b479296cc2c5fa0f3c00fc823e5fc192a04c6a49 yt/gui/reason/bottle_mods.py
--- a/yt/gui/reason/bottle_mods.py
+++ b/yt/gui/reason/bottle_mods.py
@@ -48,9 +48,25 @@
 def notify_route(watcher):
     route_watchers.append(watcher)
 
+class BinaryDelivery(object):
+    delivered = False
+    payload = ""
+    def __init__(self, payload):
+        self.payload = payload
+
+    def get(self):
+        # We set our 
+        p = self.payload
+        if p == "":
+            response.status = 404
+            return
+        self.payload = ""
+        return p
+
 class PayloadHandler(object):
     _shared_state = {}
     payloads = None
+    binary_payloads = None
     recorded_payloads = None
     multicast_ids = None
     multicast_payloads = None
@@ -59,6 +75,7 @@
     event = None
     count = 0
     debug = False
+    _prefix = ""
 
     def __new__(cls, *p, **k):
         self = object.__new__(cls, *p, **k)
@@ -72,6 +89,7 @@
         if self.event is None: self.event = threading.Event()
         if self.multicast_payloads is None: self.multicast_payloads = {}
         if self.multicast_ids is None: self.multicast_ids = {}
+        if self.binary_payloads is None: self.binary_payloads = []
 
     def deliver_payloads(self):
         with self.lock:
@@ -92,6 +110,8 @@
 
     def add_payload(self, to_add):
         with self.lock:
+            if "binary" in to_add:
+                self._add_binary_payload(to_add)
             self.payloads.append(to_add)
             # Does this next part need to be in the lock?
             if to_add.get("widget_id", None) in self.multicast_ids:
@@ -101,6 +121,16 @@
             if self.debug:
                 sys.__stderr__.write("**** Adding payload of type %s\n" % (to_add['type']))
 
+    def _add_binary_payload(self, bp):  
+        # This shouldn't be called by anybody other than add_payload.
+        bdata = bp.pop(bp['binary']) # Get the binary data
+        bpserver = BinaryDelivery(bdata)
+        self.binary_payloads.append(bpserver)
+        uu = uuid.uuid4().hex
+        bp['binary'] = uu
+        route("%s/%s" % (self._prefix, uu))(bpserver.get)
+        sys.__stderr__.write("**** Adding binary payload to %s\n" % (uu))
+
     def replay_payloads(self):
         return self.recorded_payloads
 


diff -r f95fdf42831691af785f85b45a48efbdfb729052 -r b479296cc2c5fa0f3c00fc823e5fc192a04c6a49 yt/gui/reason/extdirect_repl.py
--- a/yt/gui/reason/extdirect_repl.py
+++ b/yt/gui/reason/extdirect_repl.py
@@ -219,6 +219,7 @@
         self.locals['widget_store'] = self.widget_store
 
     def activate(self):
+        self.payload_handler._prefix = self._global_token
         self._setup_logging_handlers()
         # Setup our heartbeat
         self.last_heartbeat = time.time()


diff -r f95fdf42831691af785f85b45a48efbdfb729052 -r b479296cc2c5fa0f3c00fc823e5fc192a04c6a49 yt/gui/reason/html/app/controller/widgets/Scene.js
--- a/yt/gui/reason/html/app/controller/widgets/Scene.js
+++ b/yt/gui/reason/html/app/controller/widgets/Scene.js
@@ -242,7 +242,6 @@
     },
 
     renderPath: function() {
-        
         var t = new Ext.XTemplate("[[{0}, {1}, {2}, {3}], ",
                                   " [{4}, {5}, {6}, {7}], ",
                                   " [{8}, {9}, {10}, {11}], ",



https://bitbucket.org/yt_analysis/yt/changeset/54d93c92c7d3/
changeset:   54d93c92c7d3
branch:      yt
user:        samskillman
date:        2012-06-23 22:12:22
summary:     Adding attempt at returning camera path
affected #:  2 files

diff -r b479296cc2c5fa0f3c00fc823e5fc192a04c6a49 -r 54d93c92c7d3bcbecf6a58d824bfccf4d03d8310 yt/gui/reason/widget_store.py
--- a/yt/gui/reason/widget_store.py
+++ b/yt/gui/reason/widget_store.py
@@ -28,6 +28,7 @@
 from .bottle_mods import PayloadHandler, lockit
 from .widget_builders import RenderingScene, get_corners, get_isocontour
 from yt.visualization.plot_window import PWViewerExtJS
+from yt.visualization.volume_rendering.create_spline import create_spline
 import uuid
 
 _phase_plot_mds = """<pre>
@@ -253,6 +254,24 @@
                                  'max_level': int(self.pf.h.max_level)})
         return
 
+    def render_path(self, views, times, N):
+        # Assume that path comes in as a list of matrice
+        # Assume original vector is (0., 0., 1.), up is (0., 1., 0.)
+        # for matrix in matrices:
+
+        views = [na.array(view) for view in views]
+        
+        times = na.linspace(0.0,1.0,len(times))
+        norm = na.array([0.,0.,1.,1.])
+        up = na.array([0.,1.,0.,1.])
+        centers = na.array([na.dot(R, norm) for R in views])
+        ups = na.array([na.dot(R,up) for R in views])
+        x,y,z = [create_spline(times, centers[:,i], na.linspace(0.0,1.0,N)) for i in [0,1,2]]
+        #fx,fy,fz = [create_spline(times, focuses[:,i], na.linspace(0.0,1.0,N)) for i in [0,1,2]]
+        ux,uy,uz = [create_spline(times, ups[:,i], na.linspace(0.0,1.0,N)) for i in [0,1,2]]
+        fx, fy, fz = 0,0,0
+        return [x,y,z], [fx,fy,fz], [ux,uy,uz]
+
     def deliver_streamlines(self):
         pf = PayloadHandler()
         pass


diff -r b479296cc2c5fa0f3c00fc823e5fc192a04c6a49 -r 54d93c92c7d3bcbecf6a58d824bfccf4d03d8310 yt/visualization/volume_rendering/camera.py
--- a/yt/visualization/volume_rendering/camera.py
+++ b/yt/visualization/volume_rendering/camera.py
@@ -229,6 +229,9 @@
         self.back_center =  center - 0.5*width[2]*unit_vectors[2]
         self.front_center = center + 0.5*width[2]*unit_vectors[2]         
 
+    def update_view_from_matrix(self, mat):
+        pass
+
     def look_at(self, new_center, north_vector = None):
         r"""Change the view direction based on a new focal point.
 



https://bitbucket.org/yt_analysis/yt/changeset/79e8d2ad7cff/
changeset:   79e8d2ad7cff
branch:      yt
user:        samskillman
date:        2012-06-23 22:22:14
summary:     putting path in a list of lists in the payload
affected #:  1 file

diff -r 54d93c92c7d3bcbecf6a58d824bfccf4d03d8310 -r 79e8d2ad7cff4e94e597e2fff12df3ac5ac288a8 yt/gui/reason/widget_store.py
--- a/yt/gui/reason/widget_store.py
+++ b/yt/gui/reason/widget_store.py
@@ -269,8 +269,18 @@
         x,y,z = [create_spline(times, centers[:,i], na.linspace(0.0,1.0,N)) for i in [0,1,2]]
         #fx,fy,fz = [create_spline(times, focuses[:,i], na.linspace(0.0,1.0,N)) for i in [0,1,2]]
         ux,uy,uz = [create_spline(times, ups[:,i], na.linspace(0.0,1.0,N)) for i in [0,1,2]]
-        fx, fy, fz = 0,0,0
-        return [x,y,z], [fx,fy,fz], [ux,uy,uz]
+        fx, fy, fz = na.zeros(N), na.zeros(N), na.zeros(N)
+
+        path = [[x.tolist(), y.tolist(), z.tolist()],
+                [fx.tolist(), fy.tolist(), fz.tolist()], 
+                [ux.tolist(), uy.tolist(), uz.tolist()]]
+    
+        ph = PayloadHandler()
+        ph.widget_payload(self, {'ptype':'camerapath',
+                                 'data':path,})
+
+        return
+
 
     def deliver_streamlines(self):
         pf = PayloadHandler()



https://bitbucket.org/yt_analysis/yt/changeset/468cbee6365a/
changeset:   468cbee6365a
branch:      yt
user:        MatthewTurk
date:        2012-06-23 22:35:33
summary:     Camera path now gets data from the server and the slider turns on and off as
you render.  Sliding the slider moves you along the camera path.
affected #:  4 files

diff -r 79e8d2ad7cff4e94e597e2fff12df3ac5ac288a8 -r 468cbee6365ac5033f67761a1a4e0e61c9b968c2 yt/gui/reason/html/app/controller/widgets/Scene.js
--- a/yt/gui/reason/html/app/controller/widgets/Scene.js
+++ b/yt/gui/reason/html/app/controller/widgets/Scene.js
@@ -30,6 +30,7 @@
     requires: ['Reason.view.widgets.Scene',
                'Reason.view.widgets.IsocontourCreator',
                'Reason.store.widgets.CameraKeyFrames',
+               'Reason.store.widgets.CameraPathElements',
                'Reason.store.widgets.SceneWidgets',
                'Ext.ux.CheckColumn'],
     templates: {
@@ -47,6 +48,7 @@
         ["#keyframeview", "select", "shiftToKeyframe"],
         ["#widgetEnabled", "checkchange", "toggleWidgetEnabled"],
         ["#addIsocontour", "click", "createIsocontour"],
+        ["#cameraPathSlider", "change", "updateCameraPosition"],
     ],
 
     /* These call templates */
@@ -58,6 +60,7 @@
         { ref:'scenePanel', selector: '#scenepanel' },
         { ref:'keyFrameView', selector: '#keyframeview' },
         { ref:'widgetPanel', selector: '#widgetlist'},
+        { ref:'cameraPathSlider', selector: '#cameraPathSlider'},
     ],
 
     /* key: , shift: and tpl: */
@@ -70,6 +73,8 @@
                               payload['max_level']);
         } else if (payload['ptype'] == 'isocontour') {
             this.addIsocontour(payload['vert'], payload['normals']);
+        } else if (payload['ptype'] == 'camerapath') {
+            this.updateCameraPathElements(payload['data']);
         } else {
             console.log("Unknown payload type received for 3D scene: " +
                         payload['ptype']);
@@ -86,6 +91,7 @@
         this.applyExecuteHandlers(this.dataView);
         this.keyFrames = Ext.create("Reason.store.widgets.CameraKeyFrames");
         this.getKeyFrameView().bindStore(this.keyFrames);
+        this.pathElements = Ext.create("Reason.store.widgets.CameraPathElements");
         this.widgets = Ext.create("Reason.store.widgets.SceneWidgets");
         this.getWidgetPanel().bindStore(this.widgets);
         this.fieldStore = Ext.create("Reason.store.Fields")
@@ -218,6 +224,8 @@
     },
 
     addKeyframe: function() {
+        this.getCameraPathSlider().setValue(0);
+        this.getCameraPathSlider().disable();
         var v = this.renderer.camera.view;
         var va = v.toArray();
         this.keyFrames.add({
@@ -247,7 +255,7 @@
                                   " [{8}, {9}, {10}, {11}], ",
                                   " [{12}, {13}, {14}, {15}]],\n");
         var cmdt = new Ext.XTemplate("widget_store['{0}'].render_path(\n",
-                                     "[{1}]\n,[{2}], 100)");
+                                     "[{1}]\n,[{2}], 101)");
         var path = "";
         var times = "";
         Ext.each(this.keyFrames.data.items, function(rec, ind, all) {
@@ -258,4 +266,26 @@
         reason.server.execute(cmd);
     },
 
+    updateCameraPathElements: function(elements) {
+        var cpe = this.pathElements;
+        var i;
+        cpe.removeAll();
+        for (i = 0; i < elements[0].length; i = i + 1) {
+            cpe.add({position: elements[0][i],
+                     focus: elements[1][i],
+                     up: elements[2][i]});
+        }
+        v = this.getCameraPathSlider().enable();
+    },
+
+    updateCameraPosition: function(b, e) {
+        v = this.getCameraPathSlider().getValue();
+        console.log(v);
+        rec = this.pathElements.data.items[v].data;
+        this.renderer.camera.position = rec.position;
+        this.renderer.camera.focus = rec.focus;
+        this.renderer.camera.up = rec.up;
+        this.renderer.render();
+    },
+
 });


diff -r 79e8d2ad7cff4e94e597e2fff12df3ac5ac288a8 -r 468cbee6365ac5033f67761a1a4e0e61c9b968c2 yt/gui/reason/html/app/store/widgets/CameraPathElements.js
--- /dev/null
+++ b/yt/gui/reason/html/app/store/widgets/CameraPathElements.js
@@ -0,0 +1,36 @@
+/**********************************************************************
+Camera Path Element store for Reason
+
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2012 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define('Reason.store.widgets.CameraPathElements', {
+    extend: 'Ext.data.Store',
+    id: 'camerapathelements',
+    fields: [
+       {name: 'position'},
+       {name: 'focus'},
+       {name: 'up'},
+    ],
+    data: [],
+});
+


diff -r 79e8d2ad7cff4e94e597e2fff12df3ac5ac288a8 -r 468cbee6365ac5033f67761a1a4e0e61c9b968c2 yt/gui/reason/html/app/view/widgets/Scene.js
--- a/yt/gui/reason/html/app/view/widgets/Scene.js
+++ b/yt/gui/reason/html/app/view/widgets/Scene.js
@@ -48,6 +48,7 @@
         }, {
             xtype: 'multislider',
             itemId: 'cameraPathSlider',
+            disabled: true,
             minValue: 0,
             maxValue: 100,
             increment: 1,


diff -r 79e8d2ad7cff4e94e597e2fff12df3ac5ac288a8 -r 468cbee6365ac5033f67761a1a4e0e61c9b968c2 yt/gui/reason/widget_store.py
--- a/yt/gui/reason/widget_store.py
+++ b/yt/gui/reason/widget_store.py
@@ -266,14 +266,13 @@
         up = na.array([0.,1.,0.,1.])
         centers = na.array([na.dot(R, norm) for R in views])
         ups = na.array([na.dot(R,up) for R in views])
-        x,y,z = [create_spline(times, centers[:,i], na.linspace(0.0,1.0,N)) for i in [0,1,2]]
-        #fx,fy,fz = [create_spline(times, focuses[:,i], na.linspace(0.0,1.0,N)) for i in [0,1,2]]
-        ux,uy,uz = [create_spline(times, ups[:,i], na.linspace(0.0,1.0,N)) for i in [0,1,2]]
-        fx, fy, fz = na.zeros(N), na.zeros(N), na.zeros(N)
-
-        path = [[x.tolist(), y.tolist(), z.tolist()],
-                [fx.tolist(), fy.tolist(), fz.tolist()], 
-                [ux.tolist(), uy.tolist(), uz.tolist()]]
+        pos = na.empty((N,3), dtype="float64")
+        uv = na.empty((N,3), dtype="float64")
+        for i in range(3):
+            pos[:,i] = create_spline(times, centers[:,i], na.linspace(0.0,1.0,N))
+            uv[:,i] = create_spline(times, ups[:,i], na.linspace(0.0,1.0,N))
+        f = na.zeros((N,3), dtype="float64")
+        path = [pos.tolist(), f.tolist(), uv.tolist()]
     
         ph = PayloadHandler()
         ph.widget_payload(self, {'ptype':'camerapath',



https://bitbucket.org/yt_analysis/yt/changeset/77bc3edd6139/
changeset:   77bc3edd6139
branch:      yt
user:        MatthewTurk
date:        2012-06-23 23:57:33
summary:     Binary payloads can now be multiple-component, and the grid and level arrays
have been converted to these.
affected #:  5 files

diff -r 468cbee6365ac5033f67761a1a4e0e61c9b968c2 -r 77bc3edd613908763697135f7eccbe5ab0108118 yt/gui/reason/bottle_mods.py
--- a/yt/gui/reason/bottle_mods.py
+++ b/yt/gui/reason/bottle_mods.py
@@ -24,16 +24,18 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """
 
+import uuid
+import json
+import logging, threading
+import sys
+import urllib, urllib2
+import numpy as na
+
 from yt.utilities.bottle import \
     server_names, debug, route, run, request, ServerAdapter, response
-import uuid
 from extdirect_router import DirectRouter, DirectProviderDefinition
-import json
-import logging, threading
 from yt.utilities.logger import ytLogger as mylog
 from yt.funcs import *
-import sys
-import urllib, urllib2
 
 route_functions = {}
 route_watchers = []
@@ -123,13 +125,18 @@
 
     def _add_binary_payload(self, bp):  
         # This shouldn't be called by anybody other than add_payload.
-        bdata = bp.pop(bp['binary']) # Get the binary data
-        bpserver = BinaryDelivery(bdata)
-        self.binary_payloads.append(bpserver)
-        uu = uuid.uuid4().hex
-        bp['binary'] = uu
-        route("%s/%s" % (self._prefix, uu))(bpserver.get)
-        sys.__stderr__.write("**** Adding binary payload to %s\n" % (uu))
+        bkeys = ensure_list(bp['binary'])
+        bp['binary'] = []
+        for bkey in bkeys:
+            bdata = bp.pop(bkey) # Get the binary data
+            if isinstance(bdata, na.ndarray):
+                bdata = bdata.tostring()
+            bpserver = BinaryDelivery(bdata)
+            self.binary_payloads.append(bpserver)
+            uu = uuid.uuid4().hex
+            bp['binary'].append((bkey, uu))
+            route("%s/%s" % (self._prefix, uu))(bpserver.get)
+            sys.__stderr__.write("**** Adding binary payload to %s\n" % (uu))
 
     def replay_payloads(self):
         return self.recorded_payloads


diff -r 468cbee6365ac5033f67761a1a4e0e61c9b968c2 -r 77bc3edd613908763697135f7eccbe5ab0108118 yt/gui/reason/html/app/controller/WidgetDirector.js
--- a/yt/gui/reason/html/app/controller/WidgetDirector.js
+++ b/yt/gui/reason/html/app/controller/WidgetDirector.js
@@ -134,10 +134,49 @@
         }
         /*console.log("Directing payload for " + payload['widget_id'] +
                     " to resultId " + resultId);*/
+        if (payload['binary'] != null) {
+            this.loadBinaryData(payload);
+            return;
+        }
         var widgetInfo = this.getWidgetInstancesStore().getAt(resultId).data;
         widgetInfo['widget'].applyPayload(payload);
     },
 
+    loadBinaryData: function(payload) {
+        /* https://developer.mozilla.org/en/using_xmlhttprequest
+           including progress */
+        var req = new XMLHttpRequest();
+        var bkeys = payload['binary'];
+        var nLeft = bkeys.length;
+        var bkey = bkeys[nLeft - 1];
+        var director = this;
+        console.log(bkeys);
+        console.log(nLeft);
+        console.log("" + bkey[0] + "  " + bkey[1]);
+        payload['binary'] = null;
+        req.open("GET", bkey[1], true);
+        req.responseType = "arraybuffer";
+        onLoad = function(e) {
+            payload[bkey[0]] = req.response;
+            console.log("RECEIVED BINARY PAYLOAD " + bkey[0]);
+            nLeft = nLeft - 1;
+            if (nLeft == 0) {
+              console.log("SENDING PAYLOAD UPSTREAM");
+              director.sendPayload(payload);
+            } else {
+              console.log("NOT SENDING UPSTREAM");
+              bkey = bkeys[nLeft - 1];
+              req.open("GET", bkey[1], true);
+              req.responseType = "arraybuffer";
+              req.onload = onLoad;
+              req.send();
+              exaine = payload;
+            }
+        }
+        req.onload = onLoad;
+        req.send();
+    },
+
     enableDebug: function() {
         if(this.instanceView) {return;}
         this.instanceView = Ext.widget('widgetinstancesgrid');


diff -r 468cbee6365ac5033f67761a1a4e0e61c9b968c2 -r 77bc3edd613908763697135f7eccbe5ab0108118 yt/gui/reason/html/app/controller/widgets/Scene.js
--- a/yt/gui/reason/html/app/controller/widgets/Scene.js
+++ b/yt/gui/reason/html/app/controller/widgets/Scene.js
@@ -69,8 +69,10 @@
 
     applyPayload: function(payload) {
         if (payload['ptype'] == 'grid_lines') {
-            this.addGridLines(payload['corners'], payload['levels'],
-                              payload['max_level']);
+            corners = new Float64Array(payload['corners']);
+            levels = new Int32Array(payload['levels']);
+            payload['corners'] = payload['levels'] = null;
+            this.addGridLines(corners, levels, payload['max_level']);
         } else if (payload['ptype'] == 'isocontour') {
             this.addIsocontour(payload['vert'], payload['normals']);
         } else if (payload['ptype'] == 'camerapath') {
@@ -127,9 +129,10 @@
     },
 
     addGridLines: function(corners, levels, maxLevel) {
-        var i, g, n, p;
+        var i, g, n, p, offset, ind;
         var order1 = [0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3];
         var order2 = [1, 2, 3, 0, 5, 6, 7, 4, 4, 5, 6, 7];
+        var nv = levels.length;
         gw = [];
         for (i = 0; i < maxLevel + 1; i = i + 1) {
             var grids = new X.mesh();
@@ -142,18 +145,20 @@
             });
             grids.ga = "LINES";
         }
+        examine = {n: n, p: p, corners: corners};
+        var i0, i1, i2;
         Ext.each(levels, function(level, index, allLevels) {
             p = gw[level].points;
             n = gw[level].normals;
             for (i = 0; i < 12; i = i + 1) {
                 n.add(1.0, 0.0, 0.0);
                 n.add(1.0, 0.0, 0.0);
-                p.add(corners[order1[i]][0][index],
-                      corners[order1[i]][1][index],
-                      corners[order1[i]][2][index]);
-                p.add(corners[order2[i]][0][index],
-                      corners[order2[i]][1][index],
-                      corners[order2[i]][2][index]);
+                p.add(corners[(((order1[i] * 3 + 0)*nv)+index)],
+                      corners[(((order1[i] * 3 + 1)*nv)+index)],
+                      corners[(((order1[i] * 3 + 2)*nv)+index)]);
+                p.add(corners[(((order2[i] * 3 + 0)*nv)+index)],
+                      corners[(((order2[i] * 3 + 1)*nv)+index)],
+                      corners[(((order2[i] * 3 + 2)*nv)+index)]);
             }
         });
         for (i = 0; i < maxLevel + 1; i = i + 1) {


diff -r 468cbee6365ac5033f67761a1a4e0e61c9b968c2 -r 77bc3edd613908763697135f7eccbe5ab0108118 yt/gui/reason/widget_builders.py
--- a/yt/gui/reason/widget_builders.py
+++ b/yt/gui/reason/widget_builders.py
@@ -78,8 +78,8 @@
 def get_corners(pf, max_level=None):
     DL = pf.domain_left_edge[None,:,None]
     DW = pf.domain_width[None,:,None]/100.0
-    corners = ((pf.h.grid_corners-DL)/DW).tolist()
-    levels = pf.h.grid_levels.tolist()
+    corners = ((pf.h.grid_corners-DL)/DW)
+    levels = pf.h.grid_levels
     return corners, levels
 
 def get_isocontour(pf, field, value=None, rel_val = False):


diff -r 468cbee6365ac5033f67761a1a4e0e61c9b968c2 -r 77bc3edd613908763697135f7eccbe5ab0108118 yt/gui/reason/widget_store.py
--- a/yt/gui/reason/widget_store.py
+++ b/yt/gui/reason/widget_store.py
@@ -242,13 +242,15 @@
             n = na.cross(vert[i*3,:], vert[i*3+1,:])
             normals[i*3:i*3+3,:] = n[None,:]
         ph.widget_payload(self, {'ptype':'isocontour',
-                                 'vert':vert.tolist(),
+                                 'binary':'vert',
+                                 'vert':vert,
                                  'normals':normals.tolist()})
 
     def deliver_gridlines(self):
         ph = PayloadHandler()
         corners, levels = get_corners(self.pf)
         ph.widget_payload(self, {'ptype':'grid_lines',
+                                 'binary': ['corners', 'levels'],
                                  'corners': corners,
                                  'levels': levels,
                                  'max_level': int(self.pf.h.max_level)})



https://bitbucket.org/yt_analysis/yt/changeset/3e5cdbebd244/
changeset:   3e5cdbebd244
branch:      yt
user:        MatthewTurk
date:        2012-06-24 00:19:05
summary:     Vertices and normals are binary for the isocontours.  Much, much faster.  Seems
to be a lingering issue with scoping.
affected #:  3 files

diff -r 77bc3edd613908763697135f7eccbe5ab0108118 -r 3e5cdbebd244ea70359ed5b50955be79b45f84ee yt/gui/reason/bottle_mods.py
--- a/yt/gui/reason/bottle_mods.py
+++ b/yt/gui/reason/bottle_mods.py
@@ -53,11 +53,14 @@
 class BinaryDelivery(object):
     delivered = False
     payload = ""
-    def __init__(self, payload):
+    def __init__(self, payload, name = ""):
+        self.name = name
         self.payload = payload
 
     def get(self):
         # We set our 
+        sys.__stderr__.write("REQUESTED A BINARY PAYLOAD %s (%s)\n" % (
+            self.name, len(self.payload)))
         p = self.payload
         if p == "":
             response.status = 404
@@ -131,12 +134,13 @@
             bdata = bp.pop(bkey) # Get the binary data
             if isinstance(bdata, na.ndarray):
                 bdata = bdata.tostring()
-            bpserver = BinaryDelivery(bdata)
+            bpserver = BinaryDelivery(bdata, bkey)
             self.binary_payloads.append(bpserver)
             uu = uuid.uuid4().hex
             bp['binary'].append((bkey, uu))
             route("%s/%s" % (self._prefix, uu))(bpserver.get)
-            sys.__stderr__.write("**** Adding binary payload to %s\n" % (uu))
+            sys.__stderr__.write("**** Adding binary payload (%s) to %s\n" % (
+                    bkey, uu))
 
     def replay_payloads(self):
         return self.recorded_payloads


diff -r 77bc3edd613908763697135f7eccbe5ab0108118 -r 3e5cdbebd244ea70359ed5b50955be79b45f84ee yt/gui/reason/html/app/controller/widgets/Scene.js
--- a/yt/gui/reason/html/app/controller/widgets/Scene.js
+++ b/yt/gui/reason/html/app/controller/widgets/Scene.js
@@ -69,11 +69,12 @@
 
     applyPayload: function(payload) {
         if (payload['ptype'] == 'grid_lines') {
-            corners = new Float64Array(payload['corners']);
-            levels = new Int32Array(payload['levels']);
-            payload['corners'] = payload['levels'] = null;
-            this.addGridLines(corners, levels, payload['max_level']);
+            payload['corners'] = new Float64Array(payload['corners']);
+            payload['levels'] = new Int32Array(payload['levels']);
+            this.addGridLines(payload['corners'], payload['levels'], payload['max_level']);
         } else if (payload['ptype'] == 'isocontour') {
+            payload['vert'] = new Float64Array(payload['vert']);
+            payload['normals'] = new Float64Array(payload['normals']);
             this.addIsocontour(payload['vert'], payload['normals']);
         } else if (payload['ptype'] == 'camerapath') {
             this.updateCameraPathElements(payload['data']);
@@ -193,14 +194,7 @@
     addIsocontour: function(vertices, normals) {
         console.log("Adding isocontours ...");
         var i, g, n, p;
-        Ext.MessageBox.show({
-            title : "Adding Isocontour Vertices",
-            width: 300,
-            msg: "Updating ...",
-            progress: true,
-            closable: false,
-        });
-        var nv = vertices.length;
+        var nv = vertices.length/3;
         var last = 0;
         var surf = new X.mesh();
         this.widgets.add({
@@ -212,17 +206,15 @@
         surf.ga = "TRIANGLES";
         p = surf.points;
         n = surf.normals;
-        Ext.each(vertices, function(vert, index, allVerts) {
-            if ((index - last) > ( nv / 100.0)) {
-                Ext.MessageBox.updateProgress(
-                        (index / nv),
-                        Math.round(100*index/nv) + '% completed');
-                last = index;
-            }
-            p.add(vert[0], vert[1], vert[2]);
-            n.add(normals[index][0], normals[index][1], normals[index][2]);
-        });
-        Ext.MessageBox.hide();
+
+        for (index = 0; index < nv; index = index + 1) {
+            p.add(vertices[index * 3 + 0],
+                  vertices[index * 3 + 1],
+                  vertices[index * 3 + 2]);
+            n.add(normals[index * 3 + 0],
+                  normals[index * 3 + 1],
+                  normals[index * 3 + 2]);
+        }
         surf.color = [1.0, 0.0, 0.0];
         this.renderer.add(surf);
         this.renderer.render();


diff -r 77bc3edd613908763697135f7eccbe5ab0108118 -r 3e5cdbebd244ea70359ed5b50955be79b45f84ee yt/gui/reason/widget_store.py
--- a/yt/gui/reason/widget_store.py
+++ b/yt/gui/reason/widget_store.py
@@ -242,9 +242,9 @@
             n = na.cross(vert[i*3,:], vert[i*3+1,:])
             normals[i*3:i*3+3,:] = n[None,:]
         ph.widget_payload(self, {'ptype':'isocontour',
-                                 'binary':'vert',
+                                 'binary': ['vert', 'normals'],
                                  'vert':vert,
-                                 'normals':normals.tolist()})
+                                 'normals':normals})
 
     def deliver_gridlines(self):
         ph = PayloadHandler()



https://bitbucket.org/yt_analysis/yt/changeset/679c07f26803/
changeset:   679c07f26803
branch:      yt
user:        MatthewTurk
date:        2012-06-24 00:43:17
summary:     Binary delivery for multiple payloads works with a few modifications to the
closure in the delivery function.
affected #:  2 files

diff -r 3e5cdbebd244ea70359ed5b50955be79b45f84ee -r 679c07f268032343d91706ecafff8abfd6b989bd yt/gui/reason/bottle_mods.py
--- a/yt/gui/reason/bottle_mods.py
+++ b/yt/gui/reason/bottle_mods.py
@@ -56,11 +56,13 @@
     def __init__(self, payload, name = ""):
         self.name = name
         self.payload = payload
+        #sys.__stderr__.write("CREATING A BINARY PAYLOAD %s (%s)\n" % (
+        #    self.name, len(self.payload)))
 
     def get(self):
         # We set our 
-        sys.__stderr__.write("REQUESTED A BINARY PAYLOAD %s (%s)\n" % (
-            self.name, len(self.payload)))
+        #sys.__stderr__.write("REQUESTED A BINARY PAYLOAD %s (%s)\n" % (
+        #    self.name, len(self.payload)))
         p = self.payload
         if p == "":
             response.status = 404
@@ -139,8 +141,9 @@
             uu = uuid.uuid4().hex
             bp['binary'].append((bkey, uu))
             route("%s/%s" % (self._prefix, uu))(bpserver.get)
-            sys.__stderr__.write("**** Adding binary payload (%s) to %s\n" % (
-                    bkey, uu))
+            if self.debug:
+                sys.__stderr__.write(
+                    "**** Adding binary payload (%s) to %s\n" % (bkey, uu))
 
     def replay_payloads(self):
         return self.recorded_payloads


diff -r 3e5cdbebd244ea70359ed5b50955be79b45f84ee -r 679c07f268032343d91706ecafff8abfd6b989bd yt/gui/reason/html/app/controller/WidgetDirector.js
--- a/yt/gui/reason/html/app/controller/WidgetDirector.js
+++ b/yt/gui/reason/html/app/controller/WidgetDirector.js
@@ -142,39 +142,36 @@
         widgetInfo['widget'].applyPayload(payload);
     },
 
-    loadBinaryData: function(payload) {
+    loadBinaryData: function(payload1) {
         /* https://developer.mozilla.org/en/using_xmlhttprequest
            including progress */
-        var req = new XMLHttpRequest();
-        var bkeys = payload['binary'];
-        var nLeft = bkeys.length;
-        var bkey = bkeys[nLeft - 1];
-        var director = this;
-        console.log(bkeys);
-        console.log(nLeft);
-        console.log("" + bkey[0] + "  " + bkey[1]);
-        payload['binary'] = null;
-        req.open("GET", bkey[1], true);
-        req.responseType = "arraybuffer";
-        onLoad = function(e) {
-            payload[bkey[0]] = req.response;
-            console.log("RECEIVED BINARY PAYLOAD " + bkey[0]);
-            nLeft = nLeft - 1;
-            if (nLeft == 0) {
-              console.log("SENDING PAYLOAD UPSTREAM");
-              director.sendPayload(payload);
-            } else {
-              console.log("NOT SENDING UPSTREAM");
-              bkey = bkeys[nLeft - 1];
-              req.open("GET", bkey[1], true);
-              req.responseType = "arraybuffer";
-              req.onload = onLoad;
-              req.send();
-              exaine = payload;
+        function loadBinaryPayload(payload) {
+            var req = new XMLHttpRequest();
+            var bkeys = payload['binary'];
+            var nLeft = bkeys.length;
+            var bkey = bkeys[nLeft - 1];
+            var director = this;
+            payload['binary'] = null;
+            req.open("GET", bkey[1], true);
+            req.responseType = "arraybuffer";
+            onLoad = function(e) {
+                payload[bkey[0]] = req.response;
+                nLeft = nLeft - 1;
+                if (nLeft == 0) {
+                  director.sendPayload(payload);
+                } else {
+                  bkey = bkeys[nLeft - 1];
+                  req.open("GET", bkey[1], true);
+                  req.responseType = "arraybuffer";
+                  req.onload = onLoad;
+                  req.send();
+                  exaine = payload;
+                }
             }
+            req.onload = onLoad;
+            req.send();
         }
-        req.onload = onLoad;
-        req.send();
+        loadBinaryPayload.call(this, payload1);
     },
 
     enableDebug: function() {



https://bitbucket.org/yt_analysis/yt/changeset/2ed7043295db/
changeset:   2ed7043295db
branch:      yt
user:        MatthewTurk
date:        2012-06-24 01:03:52
summary:     Using relative density values by default.
affected #:  2 files

diff -r 679c07f268032343d91706ecafff8abfd6b989bd -r 2ed7043295db669019a9aa1fe28b393ce5e19310 yt/gui/reason/html/app/view/widgets/IsocontourCreator.js
--- a/yt/gui/reason/html/app/view/widgets/IsocontourCreator.js
+++ b/yt/gui/reason/html/app/view/widgets/IsocontourCreator.js
@@ -52,6 +52,7 @@
                 fieldLabel: 'Relative Value?',
                 itemId: 'relValue',
                 value: true,
+                checked: true,
                 width: 290,
                 allowBlank:false,
               },{


diff -r 679c07f268032343d91706ecafff8abfd6b989bd -r 2ed7043295db669019a9aa1fe28b393ce5e19310 yt/gui/reason/widget_builders.py
--- a/yt/gui/reason/widget_builders.py
+++ b/yt/gui/reason/widget_builders.py
@@ -88,7 +88,7 @@
     if value is None or rel_val:
         if value is None: value = 0.5
         mi, ma = na.log10(dd.quantities["Extrema"]("Density")[0])
-        value = 10.0**(value*(mi + ma))
+        value = 10.0**(value*(ma - mi) + mi)
     vert = dd.extract_isocontours("Density", value)
     na.multiply(vert, 100, vert)
     return vert



https://bitbucket.org/yt_analysis/yt/changeset/810ad2b66969/
changeset:   810ad2b66969
branch:      yt
user:        brittonsmith
date:        2012-06-24 00:25:38
summary:     Added -r (--remote) option to yt serve to start up
a Pyro4 client.
affected #:  2 files

diff -r 111f4fa253f550d75a11d6351ba1be96a65ac6b5 -r 810ad2b66969010c9469fbd1757b8913bb468be7 yt/gui/reason/extdirect_repl.py
--- a/yt/gui/reason/extdirect_repl.py
+++ b/yt/gui/reason/extdirect_repl.py
@@ -219,7 +219,8 @@
     debug = False
     _heartbeat_timer = None
 
-    def __init__(self, base_extjs_path, locals=None):
+    def __init__(self, base_extjs_path, locals=None,
+                 use_pyro=False):
         # First we do the standard initialization
         self.extjs_file = zipfile.ZipFile(os.path.join(
             base_extjs_path, "ext-4.1.0-gpl.zip"), 'r')
@@ -245,8 +246,10 @@
         self.pflist = ExtDirectParameterFileList()
         self.executed_cell_texts = []
         self.payload_handler = PayloadHandler()
-        #self.execution_thread = ExecutionThread(self)
-        self.execution_thread = PyroExecutionThread(self)
+        if use_pyro:
+            self.execution_thread = PyroExecutionThread(self)
+        else:
+            self.execution_thread = ExecutionThread(self)
         # We pass in a reference to ourself
         self.widget_store = WidgetStore(self)
         # Now we load up all the yt.mods stuff, but only after we've finished


diff -r 111f4fa253f550d75a11d6351ba1be96a65ac6b5 -r 810ad2b66969010c9469fbd1757b8913bb468be7 yt/utilities/command_line.py
--- a/yt/utilities/command_line.py
+++ b/yt/utilities/command_line.py
@@ -1276,6 +1276,9 @@
             dict(short="-d", long="--debug", action="store_true",
                  default = False, dest="debug",
                  help="Add a debugging mode for cell execution"),
+            dict(short = "-r", long = "--remote", action = "store_true",
+                 default = False, dest="use_pyro",
+                 help = "Use with a remote Pyro4 server."),
             "opf"
             )
     description = \
@@ -1320,7 +1323,7 @@
         import yt.utilities.bottle as bottle
         from yt.gui.reason.extdirect_repl import ExtDirectREPL
         from yt.gui.reason.bottle_mods import uuid_serve_functions, PayloadHandler
-        hr = ExtDirectREPL(base_extjs_path)
+        hr = ExtDirectREPL(base_extjs_path, use_pyro=args.use_pyro)
         hr.debug = PayloadHandler.debug = args.debug
         command_line = ["pfs = []"]
         if args.find:



https://bitbucket.org/yt_analysis/yt/changeset/4a20cfe8373d/
changeset:   4a20cfe8373d
branch:      yt
user:        brittonsmith
date:        2012-06-24 00:28:15
summary:     Adding the Pyro4 task queue.
affected #:  1 file

diff -r 810ad2b66969010c9469fbd1757b8913bb468be7 -r 4a20cfe8373d66a1b5c490f08c148b485e8a778e yt/gui/reason/pyro_queue.py
--- /dev/null
+++ b/yt/gui/reason/pyro_queue.py
@@ -0,0 +1,70 @@
+"""
+Task queue to connect with reason via Pyro4.
+
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: Michigan State University
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2012 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+"""
+
+import numpy as na
+import Pyro4
+import uuid
+from yt.gui.reason.basic_repl import ProgrammaticREPL
+from yt.gui.reason.bottle_mods import PayloadHandler
+
+from yt.mods import *
+
+from yt.funcs import *
+from yt.utilities.parallel_tools.parallel_analysis_interface import \
+    _get_comm, \
+    communication_system
+from yt.utilities.parallel_tools.task_queue import \
+    TaskQueueRoot, \
+    TaskQueueNonRoot
+
+class PyroQueueRoot(object):
+    def __init__(self, comm):
+        self.comm = comm
+        self.repl = ProgrammaticREPL()
+        self.payload_handler = PayloadHandler()
+
+    def execute(self, code):
+        mylog.info('Root sending out code.')
+        code = self.comm.comm.bcast(code, root=0)
+        value = self.repl.execute(code)
+        return value
+
+    def deliver(self):
+        return self.payload_handler.deliver_payloads()
+
+class PyroQueueNonRoot(object):
+    def __init__(self, comm):
+        self.comm = comm
+        self.repl = ProgrammaticREPL()
+
+    def run(self):
+        while 1:
+            code = None
+            code = self.comm.comm.bcast(code, root=0)
+            mylog.info('Received commands from subcomm root.')
+            value = self.repl.execute(code)
+            



https://bitbucket.org/yt_analysis/yt/changeset/a82e87e271b2/
changeset:   a82e87e271b2
branch:      yt
user:        brittonsmith
date:        2012-06-24 00:29:52
summary:     Removing unnecessary imports from pyro queue.
affected #:  1 file

diff -r 4a20cfe8373d66a1b5c490f08c148b485e8a778e -r a82e87e271b2d430bd6a23f95938ffa30a0e2c50 yt/gui/reason/pyro_queue.py
--- a/yt/gui/reason/pyro_queue.py
+++ b/yt/gui/reason/pyro_queue.py
@@ -28,19 +28,12 @@
 import numpy as na
 import Pyro4
 import uuid
+
+from yt.funcs import *
+
 from yt.gui.reason.basic_repl import ProgrammaticREPL
 from yt.gui.reason.bottle_mods import PayloadHandler
 
-from yt.mods import *
-
-from yt.funcs import *
-from yt.utilities.parallel_tools.parallel_analysis_interface import \
-    _get_comm, \
-    communication_system
-from yt.utilities.parallel_tools.task_queue import \
-    TaskQueueRoot, \
-    TaskQueueNonRoot
-
 class PyroQueueRoot(object):
     def __init__(self, comm):
         self.comm = comm



https://bitbucket.org/yt_analysis/yt/changeset/b49fac6e7d2d/
changeset:   b49fac6e7d2d
branch:      yt
user:        brittonsmith
date:        2012-06-24 01:04:26
summary:     Adding script to start up task queue for reason.
affected #:  1 file

diff -r a82e87e271b2d430bd6a23f95938ffa30a0e2c50 -r b49fac6e7d2d8d8fc18d9bf0518ba054769cabd0 scripts/pyro_queue.py
--- /dev/null
+++ b/scripts/pyro_queue.py
@@ -0,0 +1,15 @@
+from yt.mods import *
+
+comm = _get_comm(())
+my_rank = comm.comm.rank
+
+if my_rank == 0:
+    my_q = PyroQueueRoot(comm)
+    Pyro4.config.HMAC_KEY = uuid.uuid4().hex
+    print "HMAC KEY", Pyro4.config.HMAC_KEY
+    Pyro4.Daemon.serveSimple(
+        {my_q: "yt.executor"},
+        ns=False)
+else:
+    my_q = PyroQueueNonRoot(comm)
+    my_q.run()



https://bitbucket.org/yt_analysis/yt/changeset/16b7344e13f3/
changeset:   16b7344e13f3
branch:      yt
user:        MatthewTurk
date:        2012-06-24 01:14:15
summary:     Moving some utilities to utils.py for Reason, and changing to executing code instead of modifying locals directly
affected #:  3 files

diff -r b49fac6e7d2d8d8fc18d9bf0518ba054769cabd0 -r 16b7344e13f39d7209895d0552ea501273c9eaac yt/gui/reason/extdirect_repl.py
--- a/yt/gui/reason/extdirect_repl.py
+++ b/yt/gui/reason/extdirect_repl.py
@@ -162,21 +162,6 @@
         return []
 
 
-def deliver_image(im):
-    if hasattr(im, 'read'):
-        img_data = base64.b64encode(im.read())
-    elif isinstance(im, types.StringTypes) and \
-         im.endswith(".png"):
-        img_data = base64.b64encode(open(im).read())
-    elif isinstance(im, types.StringTypes):
-        img_data = im
-    else:
-        raise RuntimeError
-    ph = PayloadHandler()
-    payload = {'type':'png_string',
-               'image_data':img_data}
-    ph.add_payload(payload)
-
 def reason_pylab():
     def _canvas_deliver(canvas):
         tf = tempfile.TemporaryFile()
@@ -210,6 +195,18 @@
     matplotlib.rcParams["backend"] = "module://reason_agg"
     pylab.switch_backend("module://reason_agg")
 
+_startup_template = r"""\
+import pylab
+from yt.mods import *
+from yt.gui.reason.utils import load_script, deliver_image
+from yt.gui.reason.widget_store import WidgetStore
+from yt.data_objects.static_output import _cached_pfs
+
+pylab.ion()
+data_objects = []
+widget_store = WidgetStore()
+"""
+
 class ExtDirectREPL(ProgrammaticREPL, BottleDirectRouter):
     _skip_expose = ('index')
     my_name = "ExtDirectREPL"
@@ -251,22 +248,18 @@
         else:
             self.execution_thread = ExecutionThread(self)
         # We pass in a reference to ourself
+        self.execute(_startup_template)
         self.widget_store = WidgetStore(self)
         # Now we load up all the yt.mods stuff, but only after we've finished
         # setting up.
         reason_pylab()
-        self.execute("from yt.mods import *\nimport pylab\npylab.ion()")
-        self.execute("from yt.data_objects.static_output import _cached_pfs", hide = True)
-        self.execute("data_objects = []", hide = True)
-        self.locals['load_script'] = ext_load_script
-        self.locals['deliver_image'] = deliver_image
-        self.locals['widget_store'] = self.widget_store
 
     def activate(self):
         self._setup_logging_handlers()
         # Setup our heartbeat
         self.last_heartbeat = time.time()
         self._check_heartbeat()
+        self.execute("widget_store._global_token = '%s'" % self._global_token)
         self.execution_thread.start()
 
     def exception_handler(self, exc):
@@ -495,15 +488,6 @@
                             varname = pf_varname, field_list = field_list) )
         return rv
 
-def ext_load_script(filename):
-    contents = open(filename).read()
-    payload_handler = PayloadHandler()
-    payload_handler.add_payload(
-        {'type': 'cell_contents',
-         'value': contents}
-    )
-    return
-
 class PayloadLoggingHandler(logging.StreamHandler):
     def __init__(self, *args, **kwargs):
         logging.StreamHandler.__init__(self, *args, **kwargs)


diff -r b49fac6e7d2d8d8fc18d9bf0518ba054769cabd0 -r 16b7344e13f39d7209895d0552ea501273c9eaac yt/gui/reason/utils.py
--- /dev/null
+++ b/yt/gui/reason/utils.py
@@ -0,0 +1,55 @@
+"""
+Utilities for Reason
+
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: Michigan State University
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+"""
+
+from .bottle_mods import PayloadHandler
+import base64
+import types
+
+def load_script(filename):
+    contents = open(filename).read()
+    payload_handler = PayloadHandler()
+    payload_handler.add_payload(
+        {'type': 'cell_contents',
+         'value': contents}
+    )
+    return
+
+def deliver_image(im):
+    if hasattr(im, 'read'):
+        img_data = base64.b64encode(im.read())
+    elif isinstance(im, types.StringTypes) and \
+         im.endswith(".png"):
+        img_data = base64.b64encode(open(im).read())
+    elif isinstance(im, types.StringTypes):
+        img_data = im
+    else:
+        raise RuntimeError
+    ph = PayloadHandler()
+    payload = {'type':'png_string',
+               'image_data':img_data}
+    ph.add_payload(payload)
+


diff -r b49fac6e7d2d8d8fc18d9bf0518ba054769cabd0 -r 16b7344e13f39d7209895d0552ea501273c9eaac yt/gui/reason/widget_store.py
--- a/yt/gui/reason/widget_store.py
+++ b/yt/gui/reason/widget_store.py
@@ -39,8 +39,8 @@
 """
 
 class WidgetStore(dict):
-    def __init__(self, repl):
-        self.repl = weakref.proxy(repl)
+    def __init__(self, global_token = ""):
+        self._global_token = global_token
         self.payload_handler = PayloadHandler()
         super(WidgetStore, self).__init__()
 
@@ -142,7 +142,7 @@
     def create_mapview(self, widget_name):
         widget = self[widget_name]
         # We want multiple maps simultaneously
-        uu = "/%s/%s" % (getattr(self.repl, "_global_token", ""),
+        uu = "/%s/%s" % (self._global_token,
                         str(uuid.uuid1()).replace("-","_"))
         from .pannable_map import PannableMapServer
         data = widget.data_source



https://bitbucket.org/yt_analysis/yt/changeset/77ba5ce20765/
changeset:   77ba5ce20765
branch:      yt
user:        MatthewTurk
date:        2012-06-24 01:25:02
summary:     Removing leftover javascript.
affected #:  2 files

diff -r 16b7344e13f39d7209895d0552ea501273c9eaac -r 77ba5ce207656a2897ea24229e481648d94704ba yt/gui/reason/html/js/functions.js
--- a/yt/gui/reason/html/js/functions.js
+++ /dev/null
@@ -1,687 +0,0 @@
-/**********************************************************************
-Functions for Reason
-
-Author: Cameron Hummels <chummels at gmail.com>
-Affiliation: Columbia
-Author: Jeffrey S. Oishi <jsoishi at gmail.com>
-Affiliation: KIPAC/SLAC/Stanford
-Author: Britton Smith <brittonsmith at gmail.com>
-Affiliation: MSU
-Author: Matthew Turk <matthewturk at gmail.com>
-Affiliation: Columbia University
-Homepage: http://yt-project.org/
-License:
-  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
-
-  This file is part of yt.
-
-  yt is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 3 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-***********************************************************************/
-
-function cell_finished(result) {
-    var new_log = false;
-    var cell_resulted = false;
-    var cell;
-    Ext.each(result, 
-    function(payload, index) {
-        if (payload['type'] == 'shutdown') {
-            reason.task_runner.stop(heartbeat);
-            reason.heartbeat_request = true;
-            return;
-        } else if (payload['type'] == 'cell_results') {
-            text = "<pre>"+payload['output']+"</pre>";
-            formatted_input = payload['input']
-            cell = new_cell(formatted_input, text, payload['raw_input']);
-            OutputContainer.add(cell);
-            OutputContainer.doLayout();
-            notebook.doLayout();
-            if (repl_input.locked == true) {
-                /* Assume only one locking level */
-                repl_input.locked = false;
-            } else {
-                repl_input.get("input_line").setValue("");
-            }
-            if (OutputContainer.items.length > 1) {
-                OutputContainer.body.dom.scrollTop = 
-                OutputContainer.body.dom.scrollHeight -
-                cell.body.dom.scrollHeight - 20;
-            }
-            cell_resulted = true;
-        } else if (payload['type'] == 'png_string') {
-            OutputContainer.add(new Ext.Panel({
-                autoEl:{
-                    tag:'img', 
-                    width:'25%',
-                    src:"data:image/png;base64," + payload['image_data'],
-                    id:"payload_image_" + number_images,
-                    onClick: "display_image('payload_image_" + number_images + "');"
-		        }
-            }));
-	        OutputContainer.doLayout();
-	        number_images++;
-        } else if (payload['type'] == 'cell_contents') {
-	        var input_line = repl_input.get("input_line");
-	        input_line.setValue(payload['value']);
-            repl_input.locked = true;
-        } else if (payload['type'] == 'log_entry') {
-            reason.log(payload['log_entry']);
-            new_log = true;
-        } else if (payload['type'] == 'widget') {
-            var widget_type = payload['widget_type'];
-            var widget = new widget_types[widget_type](payload['varname'],
-                                                       payload['data']);
-            widget_list[widget.id] = widget;
-            /*
-               Sometimes instantiating a widget adds some objects ...
-               Plus, often when creating a widget we disable the 
-               entry of data and whatnot. 
-            */
-            cell_resulted = true;
-        } else if (payload['type'] == 'widget_payload') {
-            var widget = widget_list[payload['widget_id']];
-            widget.accept_results(payload);
-        } else {
-            alert("Didn't know how to process " + payload['type']);
-        }
-    });
-    if (new_log == true){
-        reason.log_scroll()
-    }
-    if (cell_resulted == true) {
-        enable_input();
-    }
-}
-
-function display_image(image_id) {
-    var image = Ext.get(image_id);
-    var src = image.dom.src;
-    var virtualdom = '<html><title>Image Viewer</title><body><img src="' 
-        + src + '"/></body></html>',
-    prev = window.open('', 'image_viewer');
-    prev.document.open();
-    prev.document.write(virtualdom);
-    prev.document.close();
-}
-
-// Create a tree in the left panel with the pfs and their objects.
-function fill_tree(my_pfs) {
-    treePanel.root.removeAll();
-    Ext.each(my_pfs, function(pf, index) {
-        treePanel.root.appendChild(new Ext.tree.TreeNode({
-            text: pf.name,
-            objdata: {fn: pf.filename, varname: pf.varname, type: 'pf',
-                      field_list: pf.field_list},
-            leaf:false, 
-            expanded:true, 
-            iconCls: 'pf_icon'}));
-        this_pf = treePanel.root.lastChild
-        Ext.each(pf.objects, function(obj, obj_index) {
-            this_pf.appendChild(new Ext.tree.TreeNode(
-                {text: obj.name,
-                 leaf: true,
-                 iconCls: 'data_obj',
-                 objdata: {varname: obj.varname, type: 'obj',
-                           pfdata: this_pf.attributes.objdata},
-                 }));
-        });
-    });
-}
-
-function new_cell(input, result, raw_input) {
-    var name = "cell_" + cell_count;
-    var CellPanel = new Ext.Panel(
-        { 
-            id: name, 
-            //title: "Cell " + cell_count,
-            items: [
-                { xtype:'panel',
-                  layout: 'hbox',
-                  id:name+"_input",
-                  items: [
-                    { xtype:'panel',
-                      html:input,
-                      flex:1,
-                      boxMinHeight: 40,
-                    },
-                    { xtype: 'button',
-                      width: 24,
-                      height: 24,
-                      iconCls: 'upload',
-                      tooltip: 'Upload to Pastebin',
-                      listeners: {
-                          click: function(f, e) {
-                            yt_rpc.ExtDirectREPL.paste_text({to_paste:raw_input},
-                              function(f, a) {
-                                if (a.result['status'] == 'SUCCESS') {
-                                    var alert_text = 'Pasted cell to:<br>' + 
-                                    a.result['site']
-                                    var alert_text_rec = 'Pasted cell to: ' + 
-                                    a.result['site']
-                                    Ext.Msg.alert('Pastebin', alert_text);
-                                    var record = new logging_store.recordType(
-                                        {record: alert_text_rec });
-                                    logging_store.add(record, number_log_records++);
-                              }
-                            });
-                          }
-                        }
-                    },
-                    { xtype: 'button',
-                      width: 24,
-                      height: 24,
-                      iconCls: 'doubleuparrow',
-                      tooltip: 'Copy into current cell',
-                      listeners: {
-                          click: function(f, e) {
-                            repl_input.get('input_line').setValue(raw_input);
-                          }
-                      },
-                    },
-                  ],
-                },
-                { xtype:'panel',
-                  layout: 'hbox',
-                  items: [
-                    { xtype:'panel',
-                      id:name+"_result",
-                      autoScroll:true,
-                      flex: 1,
-                      html:result,
-                      boxMinHeight: 40,
-                    },
-                  ],
-                },
-            ]
-        }
-    );
-    cell_count++;
-    return CellPanel;
-}
-
-function getGridViewerHandler(node){
-function gridViewerHandler(item, pressed){
-    yt_rpc.ExtDirectREPL.create_grid_viewer(
-        {pfname:node.attributes.objdata.varname},
-        handle_result);
-}
-return gridViewerHandler;
-}
-
-function getGridDataViewerHandler(node){
-function gridDataViewerHandler(item, pressed){
-    yt_rpc.ExtDirectREPL.create_grid_dataview(
-        {pfname:node.attributes.objdata.varname},
-        handle_result);
-}
-return gridDataViewerHandler;
-}
-
-function getStreamlineViewerHandler(node){
-function streamlineViewerHandler(item, pressed){
-    yt_rpc.ExtDirectREPL.create_streamline_viewer(
-        {pfname:node.attributes.objdata.varname},
-        handle_result);
-}
-return streamlineViewerHandler;
-}
-
-function getIsocontourViewerHandler(node){
-function isocontourViewerHandler(item,pressed){
-    var win = new Ext.Window({
-        layout:'fit',
-        width:320,
-        height:250,
-        modal:true,
-        resizable:false,
-        draggable:false,
-        border:false,
-        title:'Isocontour Extraction in' + node,
-        items: [{
-            xtype: 'form', // FormPanel
-            labelWidth:80,
-            frame:true,
-            items: [{
-                xtype:'combo',
-                fieldLabel: 'Field',
-                id: 'field',
-                store:node.attributes.objdata.field_list,
-                width: 200,
-                allowBlank:false,
-                value: 'Density',
-                triggerAction: 'all',
-            },{
-                xtype:'combo',
-                fieldLabel: 'Sampling Field',
-                id: 'extract_field',
-                store:node.attributes.objdata.field_list,
-                width: 200,
-                allowBlank:false,
-                value: 'Temperature',
-                triggerAction: 'all',
-            },{
-                xtype:'textfield',
-                fieldLabel: 'Value',
-                id: 'value',
-                value: '1e-25',
-                width: 90,
-                allowBlank:false,
-            }],
-            buttons: [
-                {
-                    text: 'Extract',
-                    handler: function(b, e){
-                        var field = Ext.get("field").getValue();
-                        var value = Ext.get("value").getValue();
-                        var sampling_field = Ext.get("extract_field").getValue();
-                        yt_rpc.ExtDirectREPL.create_isocontours({
-                            pfname:node.attributes.objdata.varname,
-                            field:field, value:value,
-                            sampling_field:sampling_field},
-                          handle_result);
-                        disable_input();
-                        win.close();
-                    }
-                },{
-                    text: 'Cancel',
-                    handler: function(b, e){
-                        win.close();
-                    }
-                }
-            ]
-        }]
-    });
-    win.show(this);
-}
-return isocontourViewerHandler;
-}
-
-function getSliceHandler(node){
-function sliceHandler(item,pressed){
-    var win = new Ext.Window({
-        layout:'fit',
-        width:320,
-        height:250,
-        modal:true,
-        resizable:false,
-        draggable:false,
-        border:false,
-        title:'Slice Details for ' + node,
-        items: [{
-            xtype: 'form', // FormPanel
-            labelWidth:80,
-            frame:true,
-            items: [{
-                xtype:'textfield',
-                fieldLabel: 'Center X',
-                id: 'slice_x_center',
-                value: '0.5',
-                width: 90,
-                allowBlank:false,
-            },{
-                xtype:'textfield',
-                fieldLabel: 'Center Y',
-                id: 'slice_y_center',
-                value: '0.5',
-                width: 90,
-                allowBlank:false,
-            },{
-                xtype:'textfield',
-                fieldLabel: 'Center Z',
-                id: 'slice_z_center',
-                value: '0.5',
-                width: 90,
-                allowBlank:false,
-            },{
-                xtype:'combo',
-                fieldLabel: 'Axis',
-                id: 'slice_axis',
-                store:['X','Y','Z'],
-                width: 90,
-                allowBlank:false,
-                value: 'X',
-                triggerAction: 'all',
-            },{
-                xtype:'checkbox',
-                fieldLabel: 'Center on Max',
-                id: 'max_dens',
-                width: 90,
-                allowBlank:false,
-                handler: function(checkbox, checked) {
-                    if (checked == true) {
-                        this.ownerCt.get("slice_x_center").disable();
-                        this.ownerCt.get("slice_y_center").disable();
-                        this.ownerCt.get("slice_z_center").disable();
-                    } else {
-                        this.ownerCt.get("slice_x_center").enable();
-                        this.ownerCt.get("slice_y_center").enable();
-                        this.ownerCt.get("slice_z_center").enable();
-                    }
-                }
-            },{
-                xtype:'combo',
-                fieldLabel: 'Field',
-                id: 'slice_field',
-                store:node.attributes.objdata.field_list,
-                width: 200,
-                allowBlank:false,
-                value: 'Density',
-                triggerAction: 'all',
-            }],
-            buttons: [
-                {
-                    text: 'Slice',
-                    handler: function(b, e){
-                        var center = [Ext.get("slice_x_center").getValue(),
-                                      Ext.get("slice_y_center").getValue(),
-                                      Ext.get("slice_z_center").getValue()];
-                        var axis = Ext.get("slice_axis").getValue();
-                        var field = Ext.get("slice_field").getValue();
-                        var onmax = Ext.get("max_dens").getValue();
-                        yt_rpc.ExtDirectREPL.create_slice({
-                            pfname:node.attributes.objdata.varname,
-                            center: center, axis:axis, field:field, onmax:onmax},
-                          handle_result);
-                        disable_input();
-                        win.close();
-                    }
-                },{
-                    text: 'Cancel',
-                    handler: function(b, e){
-                        win.close();
-
-                    }
-                }
-            ]
-        }]
-    });
-    win.show(this);
-}
-return sliceHandler;
-}
-
-function widget_call(varname, method) {
-    var fcall = varname + "." + method;
-    yt_rpc.ExtDirectREPL.execute(
-        {code: fcall}, cell_finished);
-}
-
-function getPhasePlotHandler(node){
-function phasePlotHandler(item,pressed){
-    var win = new Ext.Window({
-        layout:'fit',
-        width:370,
-        height:220,
-        modal:true,
-        resizable:false,
-        draggable:false,
-        border:false,
-        title:'Phase Plot Details for ' + node,
-        items: [{
-            xtype: 'form', // FormPanel
-            labelWidth:80,
-            frame:true,
-            items: [ {
-                xtype:'combo',
-                fieldLabel: 'X Field',
-                id: 'x_field',
-                store:node.attributes.objdata.pfdata.field_list,
-                width: 230,
-                allowBlank:false,
-                triggerAction: 'all',
-                value: 'Density'
-            },{
-                xtype:'combo',
-                fieldLabel: 'Y Field',
-                id: 'y_field',
-                store:node.attributes.objdata.pfdata.field_list,
-                width: 230,
-                allowBlank:false,
-                triggerAction: 'all',
-                value: 'Temperature'
-            },{
-                xtype:'combo',
-                fieldLabel: 'Z Field',
-                id: 'z_field',
-                store:node.attributes.objdata.pfdata.field_list,
-                width: 230,
-                allowBlank:false,
-                triggerAction: 'all',
-                value: 'CellMassMsun'
-            },{
-                xtype:'combo',
-                fieldLabel: 'Weight Field',
-                id: 'weight',
-                store:['None'].concat(node.attributes.objdata.pfdata.field_list),
-                width: 230,
-                allowBlank:false,
-                triggerAction: 'all',
-                value: 'None'
-            }],
-            buttons: [
-                {
-                    text: 'Calculate',
-                    handler: function(b, e){
-                        var x_field = Ext.get("x_field").getValue();
-                        var y_field = Ext.get("y_field").getValue();
-                        var z_field = Ext.get("z_field").getValue();
-                        var weight = Ext.get("weight").getValue();
-                        yt_rpc.ExtDirectREPL.create_phase({
-                                objname: node.attributes.objdata.varname,
-                                /* Mirror image varnames ... */
-                                field_x: x_field,
-                                field_y: y_field,
-                                field_z: z_field,
-                                weight: weight,
-                                },
-                              handle_result);
-                        disable_input();
-                        win.close();
-                    }
-                },{
-                    text: 'Cancel',
-                    handler: function(b, e){win.close()}
-                }
-            ]
-        }]
-    });
-    win.show(this);
-}
-return phasePlotHandler;
-}
-
-function getProjectionHandler(node){
-function projectionHandler(item,pressed){
-    var win = new Ext.Window({
-        layout:'fit',
-        width:370,
-        height:220,
-        modal:true,
-        resizable:false,
-        draggable:false,
-        border:false,
-        title:'Projection Details for ' + node,
-        items: [{
-            xtype: 'form', // FormPanel
-            labelWidth:80,
-            frame:true,
-            items: [{
-                xtype:'combo',
-                fieldLabel: 'Axis',
-                id: 'axis',
-                store:['X','Y','Z'],
-                width: 90,
-                allowBlank:false,
-                triggerAction: 'all',
-                value: 'X',
-            },{
-                xtype:'checkbox',
-                fieldLabel: 'Center on Max',
-                id: 'max_dens',
-                width: 90,
-                allowBlank:false,
-                /* No handler, because no center */
-            },{
-                xtype:'combo',
-                fieldLabel: 'Field',
-                id: 'field',
-                store:node.attributes.objdata.field_list,
-                width: 230,
-                allowBlank:false,
-                triggerAction: 'all',
-                value: 'Density'
-            },{
-                xtype:'combo',
-                fieldLabel: 'Weight Field',
-                id: 'weightField',
-                store:['None'].concat(node.attributes.objdata.field_list),
-                width: 230,
-                allowBlank:false,
-                triggerAction: 'all',
-                value: 'None'
-            }],
-            buttons: [
-                {
-                    text: 'Project',
-                    handler: function(b, e){
-                        var axis = Ext.get("axis").getValue();
-                        var field = Ext.get("field").getValue();
-                        var weight = Ext.get("weightField").getValue();
-                        var onmax = Ext.get("max_dens").getValue();
-                        yt_rpc.ExtDirectREPL.create_proj({
-                                pfname: node.attributes.objdata.varname,
-                                axis: axis, field: field, weight: weight,
-                                onmax: onmax},
-                              handle_result);
-                        disable_input();
-                        win.close();
-                    }
-                },{
-                    text: 'Cancel',
-                    handler: function(b, e){win.close()}
-                }
-            ]
-        }]
-    });
-    win.show(this);
-}
-return projectionHandler;
-}
-
-function getSphereCreator(node){
-function sphereCreator(item,pressed){
-    var win = new Ext.Window({
-        layout:'fit',
-        width:320,
-        height:250,
-        modal:true,
-        resizable:false,
-        draggable:false,
-        border:false,
-        title:'Sphere Creator ' + node,
-        items: [{
-            xtype: 'form', // FormPanel
-            labelWidth:80,
-            frame:true,
-            items: [{
-                xtype:'textfield',
-                fieldLabel: 'Center X',
-                id: 'slice_x_center',
-                value: '0.5',
-                width: 90,
-                allowBlank:false,
-            },{
-                xtype:'textfield',
-                fieldLabel: 'Center Y',
-                id: 'slice_y_center',
-                value: '0.5',
-                width: 90,
-                allowBlank:false,
-            },{
-                xtype:'textfield',
-                fieldLabel: 'Center Z',
-                id: 'slice_z_center',
-                value: '0.5',
-                width: 90,
-                allowBlank:false,
-            },{
-                xtype:'textfield',
-                fieldLabel: 'Radius',
-                id: 'radius_value',
-                value: '0.5',
-                width: 90,
-                allowBlank:false,
-            },{
-                xtype:'combo',
-                fieldLabel: 'Unit',
-                id: 'radius_unit',
-                store:['unitary', '1', 'mpc', 'kpc', 'pc', 'au', 'rsun', 'cm'],
-                width: 90,
-                allowBlank:false,
-                value: 'Unitary',
-                triggerAction: 'all',
-            },{
-                xtype:'checkbox',
-                fieldLabel: 'Center on Max',
-                id: 'max_dens',
-                width: 90,
-                allowBlank:false,
-                handler: function(checkbox, checked) {
-                    if (checked == true) {
-                        this.ownerCt.get("slice_x_center").disable();
-                        this.ownerCt.get("slice_y_center").disable();
-                        this.ownerCt.get("slice_z_center").disable();
-                    } else {
-                        this.ownerCt.get("slice_x_center").enable();
-                        this.ownerCt.get("slice_y_center").enable();
-                        this.ownerCt.get("slice_z_center").enable();
-                    }
-                }
-            }],
-            buttons: [
-                {
-                    text: 'Slice',
-                    handler: function(b, e){
-                        var center = [Ext.get("slice_x_center").getValue(),
-                                      Ext.get("slice_y_center").getValue(),
-                                      Ext.get("slice_z_center").getValue()];
-                        var onmax = Ext.get("max_dens").getValue();
-                        var radius = [Ext.get("radius_value").getValue(),
-                                      Ext.get("radius_unit").getValue()]
-                        objargs = {radius: radius}
-                        if (onmax == true) {
-                            objargs['center'] = 'max';
-                        } else {
-                            objargs['center'] = center;
-                        }
-                        yt_rpc.ExtDirectREPL.object_creator({
-                            pfname:node.attributes.objdata.varname,
-                            objtype:'sphere', objargs:objargs},
-                          handle_result);
-                        disable_input();
-                        win.close();
-                    }
-                },{
-                    text: 'Cancel',
-                    handler: function(b, e){
-                        win.close();
-
-                    }
-                }
-            ]
-        }]
-    });
-    win.show(this);
-}
-return sphereCreator;
-}


diff -r 16b7344e13f39d7209895d0552ea501273c9eaac -r 77ba5ce207656a2897ea24229e481648d94704ba yt/gui/reason/html/js/reason.js
--- a/yt/gui/reason/html/js/reason.js
+++ /dev/null
@@ -1,383 +0,0 @@
-/**********************************************************************
-The main GUI facility for Reason
-
-Author: Cameron Hummels <chummels at gmail.com>
-Affiliation: Columbia
-Author: Jeffrey S. Oishi <jsoishi at gmail.com>
-Affiliation: KIPAC/SLAC/Stanford
-Author: Britton Smith <brittonsmith at gmail.com>
-Affiliation: MSU
-Author: Matthew Turk <matthewturk at gmail.com>
-Affiliation: Columbia University
-Homepage: http://yt-project.org/
-License:
-  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
-
-  This file is part of yt.
-
-  yt is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 3 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-***********************************************************************/
-
-Ext.app.Module = function(config){
-    Ext.apply(this, config);
-    Ext.app.Module.superclass.constructor.call(this);
-    this.init();
-}
-
-Ext.extend(Ext.app.Module, Ext.util.Observable, {
-    init : Ext.emptyFn
-});
-
-Reason = new Ext.app.App({
-  init: function() {
-    if (typeof(console) != "undefined") {
-        console.log('Mitchell!\nPardon me! Mitchell!')
-    }
-    this.setup_viewport();
-    // Go ahead and create the TreePanel now so that we can use it below
-    // get a reference to the HTML element with id "hideit" and add a click listener to it 
-    Ext.get("hideit").on('click', function(){
-        // get a reference to the Panel that was created with id = 'west-panel' 
-	    var w = Ext.getCmp('west-panel');
-        // expand or collapse that Panel based on its collapsed property state
-        // need to make room for six sour cream burritos
-        w.collapsed ? w.expand() : w.collapse();
-    });
-
-    /* Now we create our record store. */
-    this.logging_store = new Ext.data.Store({
-        fields: [{name:'record'}],
-        reader: new Ext.data.ArrayReader({}, [{name: 'record'}]),
-    });
-
-    this.widget_types = {}
-    this.widget_list = {}
-    this.number_log_records = 0;
-    this.number_images = 0;
-    this.cell_count = 0;
-    this.notebook = viewport.get("center-panel").get("notebook");
-    this.status_region = viewport.get("status-region");
-  },
-
-  setup_viewport: function() {
-    this.viewport = new Ext.Viewport({
-        layout: 'border',
-        items: [
-		// lazily created panel (xtype:'panel' is default)
-            {
-                xtype: 'grid',
-                store: logging_store,
-                defaults: { width: 800 },
-                columns: [ {id:'record', 
-                    sortable: false,
-                    width:800} ],
-                autofill: true,
-                region: 'south',
-                id: "status-region",
-                cls: "status-logger",
-                split: true,
-                height: 100,
-                maxSize: 200,
-                collapsible: true,
-                title: 'Status',
-                margins: '0 0 0 0',
-            }, {
-                region: 'west',
-                id: 'west-panel', // see Ext.getCmp() below
-                title: 'Data Objects',
-                split: true,
-                width: 200,
-                minSize: 175,
-                maxSize: 400,
-                collapsible: true,
-                margins: '0 0 0 5',
-                layout: {
-                    type: 'anchor',
-                },
-                items: [{
-                        xtype: 'toolbar',
-                        items: [ main_menu ],
-                    },
-                    treePanel,
-                ]
-		  // in this instance the TabPanel is not wrapped by another panel
-		  // since no title is needed, this Panel is added directly
-		  // as a Container
-            },{
-                xtype: 'tabpanel',
-                region: 'center', 
-                id: 'center-panel',
-                deferredRender: false,
-                activeTab: 0,     
-                items: [{
-                        title: 'YT',
-                        id: 'notebook',
-                        layout: 'vbox',
-                        layoutConfig: {align:'stretch'},
-                        closable: false,
-                        autoScroll: false,
-                        iconCls: 'console',
-                        items: [InputContainer, OutputContainer]
-                    }, 
-                ]
-            }
-        ]
-    });
-  },
-
-  log : function(text) {
-    this.logging_store.add({record:text}, this.number_log_records++);
-  },
-
-  log_scroll : function() {
-    this.status_region.getView().focusRow(number_log_records-1);
-  },
-
-  handle_result : function(f, a) {
-    if(a.status == false){
-        Ext.Msg.alert("Error", "Something has gone wrong.");
-        examine = {f: f, a: a};
-        return;
-    }
-    this.cell_finished(a.result);
-  },
-
-  start_heartbeat : function() {
-    this.task_runner = new Ext.util.TaskRunner();
-    this.heartbeat_request = false;
-    this.number_heartbeats = 0;
-    this.heartbeat = {
-    run:
-      function(){ if (this.heartbeat_request == true) return; 
-        this.heartbeat_request = true;
-        yt_rpc.ExtDirectREPL.heartbeat(
-            {}, function(f, a) {
-            this.heartbeat_request = false;
-            if (f != null) {
-                handle_result(f, a);
-            }})},
-    interval: 250};
-
-    this.task_runner.start(heartbeat);
-  },
-
-  enable_input : function() {
-    repl_input.body.removeClass("cell_waiting");
-    repl_input.get('input_line').setReadOnly(false);
-    repl_input.get("input_line").focus();
-    yt_rpc.ExtDirectParameterFileList.get_list_of_pfs({}, fill_tree);
-  },
-
-  disable_input : function() {
-    this.InputCell.get('input_line').setReadOnly(true);
-    this.InputCell.body.addClass("cell_waiting");
-  },
-});
-
-Reason.Interpreter = function() { 
-    var interpreter = this;
-    this.execute = function() {
-        this.disable_input();
-        yt_rpc.ExtDirectREPL.execute({
-            code:this.InputForm.get('input_line').getValue()},
-        this.handle_result);
-    };
-    this.get_contents() {
-        return this.InputForm.get('input_line').getValue();
-    }
-    this.set_contents(contents, focus) {
-        this.InputForm.get('input_line').setValue(contents);
-        if (focus == true) {
-            this.InputForm.get('input_line').focus();
-        }
-    }
-    this.InputForm = new Ext.FormPanel({
-        title: 'YT Input',
-        url: 'push',
-        flex: 0.2,
-        layout: 'fit',
-        padding: 5,
-        height: '100%',
-        flex: 1.0,
-        items: [{
-            id: 'input_line',
-            xtype: 'textarea',
-            width: '100%',
-            autoScroll: true,
-            name: 'line',
-            allowBlank: 'True',
-            bodyStyle: 'font-family: "monospace";',
-            listeners: {
-                specialkey: function(f, e){
-                    if (e.getKey() == e.ENTER) {
-                        Reason.Interpreter.execute();
-                    }
-                },
-                afterrender: function(f, e){
-                    //var input_line_drop_target_el = repl_input.get("input_line").el.dom;
-                    var input_line_drop_target_el = repl_input.body.dom;
-
-                    var input_line_drop_target = new Ext.dd.DropTarget(input_line_drop_target_el, {
-                        ddGroup     : 'pfDDgroup',
-                        notifyEnter : function(ddSource, e, data) {
-                            repl_input.body.stopFx();
-                            repl_input.body.highlight();
-                        },
-                        notifyDrop  : function(ddSource, e, data){
-
-                            var varname = data.node.attributes.objdata.varname;
-                            /* There is possibly a better way to do this, where it's also inserted correctly. */
-                            var line = Reason.Interpreter.get_contents();
-                            Reason.interpreter.set_contents(line + varname, true);
-                            return(true);
-                        }
-                    });
-                },
-            },
-        },],
-    });
-    this.InputContainer = new Ext.Panel({
-        title: 'YT Input',
-        flex: 0.3,
-        layout: {type: 'hbox',
-                 pack: 'start',
-                 align: 'stretch',
-                 },
-        items: [ interpreter.InputForm,
-                { xtype: 'button',
-                  width: 24,
-                  height: 24,
-                  iconCls: 'doubledownarrow',
-                  tooltip: 'Execute Cell',
-                  listeners: {
-                      click: function(f, e) { interpreter.execute(); }
-                  },
-                }
-               ]
-    });
-
-
-var OutputContainer = new Ext.Panel({
-    title: 'YT Output',
-    id: 'output_container',
-    autoScroll: true,
-    flex: 0.8,
-    items: []
-});
-
-TreePanel = function(
-new Ext.tree.TreePanel({
-    iconCls: 'nav',
-    id: 'tree-panel',
-    layout: 'anchor',
-    region:'west',
-    split: true,
-    anchor: '100% -35',
-    minSize: 150,
-    autoScroll: true,
-    rootVisible: false,
-    ddGroup: 'pfDDgroup',
-    enableDD: true,
-    root:new Ext.tree.TreeNode({
-        expanded:true,
-        leaf:false,
-        text:''
-    }),
-    listeners: {
-        render: {
-            fn: function() {
-                Ext.getBody().on("contextmenu", Ext.emptyFn,
-                null, {preventDefault: true});
-            }
-        },
-        dblclick: {
-            fn: function(node, e) {
-                treePanel.fireEvent("contextmenu", node, e);
-            }
-        },
-        contextmenu: {
-            fn: function(node, event){
-                var rightclickMenu;
-                if (node.attributes.objdata.type == 'obj') {
-                  rightClickMenu = new Ext.menu.Menu({
-                      items: [
-                          {
-                              text: 'Phase Plot',
-                              handler: getPhasePlotHandler(node),
-                          }, 
-                      ]
-                  });
-                } else if (node.attributes.objdata.type == 'pf') {
-                  rightClickMenu = new Ext.menu.Menu({
-                      items: [
-                          {
-                              text: 'View Grids',
-                              handler: getGridViewerHandler(node),
-                          }, {
-                              text: 'View Isocontour',
-                              handler: getIsocontourViewerHandler(node),
-                          }, {
-                              text: 'View Grid Data',
-                              handler: getGridDataViewerHandler(node),
-                          }, {
-                              text: 'Open slice',
-                              handler: getSliceHandler(node),
-                          }, {
-                              text: 'Open projection',
-                              handler: getProjectionHandler(node),
-                          /*}, {
-                              text: 'Create Sphere',
-                              handler: getSphereCreator(node), */
-                          }, /*{
-                              text: 'View Streamlines',
-                              handler: getStreamlineViewerHandler(node),
-                          }, */
-                      ]
-                  });
-                }
-                rightClickMenu.showAt(event.xy);
-            }
-        }
-    }
-});
-
-var reason;
-var examine;
-
-Ext.onReady(function(){
-    Ext.BLANK_IMAGE_URL = 'resources/resources/images/default/s.gif';
-
-    // NOTE: This is an example showing simple state management. During development,
-    // it is generally best to disable state management as dynamically-generated ids
-    // can change across page loads, leading to unpredictable results.  The developer
-    // should ensure that stable state ids are set for stateful components in real apps.
-    // it's a cold day for pontooning.
-    Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
-    reason = Reason()
-    reason.log('Welcome to yt.');
-    reason.log('After entering a line of code in the YT Input field, press shift-enter to evaluate.');
-    reason.log('4d3d3d3 engaged.');
-
-    if (!Ext.state.Manager.get("reason_welcomed", false)) {
-        Ext.MessageBox.alert("Reason v0.5",
-        "Welcome to Reason.  <br>Treat the 'YT Input' field as a YT/python intepreter.<br>Press shift-enter to evaluate.",
-        function(b,e){ repl_input.get("input_line").focus(); });
-        Ext.state.Manager.set("reason_welcomed", true);
-    } else { 
-        repl_input.get("input_line").focus();
-    }
-
-    /* Set up the heartbeat */
-    reason.start_heartbeat();
-});



https://bitbucket.org/yt_analysis/yt/changeset/ca054fb27326/
changeset:   ca054fb27326
branch:      yt
user:        samskillman
date:        2012-06-24 03:18:16
summary:     Incorrect go at keyframe interpolating.  Not getting the correct camera position
affected #:  1 file

diff -r 468cbee6365ac5033f67761a1a4e0e61c9b968c2 -r ca054fb27326567f031a951948df74b9999758d7 yt/gui/reason/widget_store.py
--- a/yt/gui/reason/widget_store.py
+++ b/yt/gui/reason/widget_store.py
@@ -264,14 +264,23 @@
         times = na.linspace(0.0,1.0,len(times))
         norm = na.array([0.,0.,1.,1.])
         up = na.array([0.,1.,0.,1.])
-        centers = na.array([na.dot(R, norm) for R in views])
-        ups = na.array([na.dot(R,up) for R in views])
+        
+        centers = na.array([na.dot(na.eye(4)*R[3,2],na.dot(R, norm)) for R in views])
+        r = views[0]
+        print r 
+        ups = na.array([na.dot(R,up)) for R in views])
+        print 'centers'
+        for center in centers: print center
+        print 'ups'
+        for up in ups: print up
+
         pos = na.empty((N,3), dtype="float64")
         uv = na.empty((N,3), dtype="float64")
+        f = na.zeros((N,3), dtype="float64")
         for i in range(3):
             pos[:,i] = create_spline(times, centers[:,i], na.linspace(0.0,1.0,N))
             uv[:,i] = create_spline(times, ups[:,i], na.linspace(0.0,1.0,N))
-        f = na.zeros((N,3), dtype="float64")
+    
         path = [pos.tolist(), f.tolist(), uv.tolist()]
     
         ph = PayloadHandler()



https://bitbucket.org/yt_analysis/yt/changeset/b13dfdb47efd/
changeset:   b13dfdb47efd
branch:      yt
user:        samskillman
date:        2012-06-24 03:20:21
summary:     Merging
affected #:  6 files

diff -r ca054fb27326567f031a951948df74b9999758d7 -r b13dfdb47efd81bab25d9a0dde73784f51bfe89f yt/gui/reason/bottle_mods.py
--- a/yt/gui/reason/bottle_mods.py
+++ b/yt/gui/reason/bottle_mods.py
@@ -24,16 +24,18 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """
 
+import uuid
+import json
+import logging, threading
+import sys
+import urllib, urllib2
+import numpy as na
+
 from yt.utilities.bottle import \
     server_names, debug, route, run, request, ServerAdapter, response
-import uuid
 from extdirect_router import DirectRouter, DirectProviderDefinition
-import json
-import logging, threading
 from yt.utilities.logger import ytLogger as mylog
 from yt.funcs import *
-import sys
-import urllib, urllib2
 
 route_functions = {}
 route_watchers = []
@@ -51,11 +53,16 @@
 class BinaryDelivery(object):
     delivered = False
     payload = ""
-    def __init__(self, payload):
+    def __init__(self, payload, name = ""):
+        self.name = name
         self.payload = payload
+        #sys.__stderr__.write("CREATING A BINARY PAYLOAD %s (%s)\n" % (
+        #    self.name, len(self.payload)))
 
     def get(self):
         # We set our 
+        #sys.__stderr__.write("REQUESTED A BINARY PAYLOAD %s (%s)\n" % (
+        #    self.name, len(self.payload)))
         p = self.payload
         if p == "":
             response.status = 404
@@ -123,13 +130,20 @@
 
     def _add_binary_payload(self, bp):  
         # This shouldn't be called by anybody other than add_payload.
-        bdata = bp.pop(bp['binary']) # Get the binary data
-        bpserver = BinaryDelivery(bdata)
-        self.binary_payloads.append(bpserver)
-        uu = uuid.uuid4().hex
-        bp['binary'] = uu
-        route("%s/%s" % (self._prefix, uu))(bpserver.get)
-        sys.__stderr__.write("**** Adding binary payload to %s\n" % (uu))
+        bkeys = ensure_list(bp['binary'])
+        bp['binary'] = []
+        for bkey in bkeys:
+            bdata = bp.pop(bkey) # Get the binary data
+            if isinstance(bdata, na.ndarray):
+                bdata = bdata.tostring()
+            bpserver = BinaryDelivery(bdata, bkey)
+            self.binary_payloads.append(bpserver)
+            uu = uuid.uuid4().hex
+            bp['binary'].append((bkey, uu))
+            route("%s/%s" % (self._prefix, uu))(bpserver.get)
+            if self.debug:
+                sys.__stderr__.write(
+                    "**** Adding binary payload (%s) to %s\n" % (bkey, uu))
 
     def replay_payloads(self):
         return self.recorded_payloads


diff -r ca054fb27326567f031a951948df74b9999758d7 -r b13dfdb47efd81bab25d9a0dde73784f51bfe89f yt/gui/reason/html/app/controller/WidgetDirector.js
--- a/yt/gui/reason/html/app/controller/WidgetDirector.js
+++ b/yt/gui/reason/html/app/controller/WidgetDirector.js
@@ -134,10 +134,46 @@
         }
         /*console.log("Directing payload for " + payload['widget_id'] +
                     " to resultId " + resultId);*/
+        if (payload['binary'] != null) {
+            this.loadBinaryData(payload);
+            return;
+        }
         var widgetInfo = this.getWidgetInstancesStore().getAt(resultId).data;
         widgetInfo['widget'].applyPayload(payload);
     },
 
+    loadBinaryData: function(payload1) {
+        /* https://developer.mozilla.org/en/using_xmlhttprequest
+           including progress */
+        function loadBinaryPayload(payload) {
+            var req = new XMLHttpRequest();
+            var bkeys = payload['binary'];
+            var nLeft = bkeys.length;
+            var bkey = bkeys[nLeft - 1];
+            var director = this;
+            payload['binary'] = null;
+            req.open("GET", bkey[1], true);
+            req.responseType = "arraybuffer";
+            onLoad = function(e) {
+                payload[bkey[0]] = req.response;
+                nLeft = nLeft - 1;
+                if (nLeft == 0) {
+                  director.sendPayload(payload);
+                } else {
+                  bkey = bkeys[nLeft - 1];
+                  req.open("GET", bkey[1], true);
+                  req.responseType = "arraybuffer";
+                  req.onload = onLoad;
+                  req.send();
+                  exaine = payload;
+                }
+            }
+            req.onload = onLoad;
+            req.send();
+        }
+        loadBinaryPayload.call(this, payload1);
+    },
+
     enableDebug: function() {
         if(this.instanceView) {return;}
         this.instanceView = Ext.widget('widgetinstancesgrid');


diff -r ca054fb27326567f031a951948df74b9999758d7 -r b13dfdb47efd81bab25d9a0dde73784f51bfe89f yt/gui/reason/html/app/controller/widgets/Scene.js
--- a/yt/gui/reason/html/app/controller/widgets/Scene.js
+++ b/yt/gui/reason/html/app/controller/widgets/Scene.js
@@ -69,9 +69,12 @@
 
     applyPayload: function(payload) {
         if (payload['ptype'] == 'grid_lines') {
-            this.addGridLines(payload['corners'], payload['levels'],
-                              payload['max_level']);
+            payload['corners'] = new Float64Array(payload['corners']);
+            payload['levels'] = new Int32Array(payload['levels']);
+            this.addGridLines(payload['corners'], payload['levels'], payload['max_level']);
         } else if (payload['ptype'] == 'isocontour') {
+            payload['vert'] = new Float64Array(payload['vert']);
+            payload['normals'] = new Float64Array(payload['normals']);
             this.addIsocontour(payload['vert'], payload['normals']);
         } else if (payload['ptype'] == 'camerapath') {
             this.updateCameraPathElements(payload['data']);
@@ -127,9 +130,10 @@
     },
 
     addGridLines: function(corners, levels, maxLevel) {
-        var i, g, n, p;
+        var i, g, n, p, offset, ind;
         var order1 = [0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3];
         var order2 = [1, 2, 3, 0, 5, 6, 7, 4, 4, 5, 6, 7];
+        var nv = levels.length;
         gw = [];
         for (i = 0; i < maxLevel + 1; i = i + 1) {
             var grids = new X.mesh();
@@ -142,18 +146,20 @@
             });
             grids.ga = "LINES";
         }
+        examine = {n: n, p: p, corners: corners};
+        var i0, i1, i2;
         Ext.each(levels, function(level, index, allLevels) {
             p = gw[level].points;
             n = gw[level].normals;
             for (i = 0; i < 12; i = i + 1) {
                 n.add(1.0, 0.0, 0.0);
                 n.add(1.0, 0.0, 0.0);
-                p.add(corners[order1[i]][0][index],
-                      corners[order1[i]][1][index],
-                      corners[order1[i]][2][index]);
-                p.add(corners[order2[i]][0][index],
-                      corners[order2[i]][1][index],
-                      corners[order2[i]][2][index]);
+                p.add(corners[(((order1[i] * 3 + 0)*nv)+index)],
+                      corners[(((order1[i] * 3 + 1)*nv)+index)],
+                      corners[(((order1[i] * 3 + 2)*nv)+index)]);
+                p.add(corners[(((order2[i] * 3 + 0)*nv)+index)],
+                      corners[(((order2[i] * 3 + 1)*nv)+index)],
+                      corners[(((order2[i] * 3 + 2)*nv)+index)]);
             }
         });
         for (i = 0; i < maxLevel + 1; i = i + 1) {
@@ -188,14 +194,7 @@
     addIsocontour: function(vertices, normals) {
         console.log("Adding isocontours ...");
         var i, g, n, p;
-        Ext.MessageBox.show({
-            title : "Adding Isocontour Vertices",
-            width: 300,
-            msg: "Updating ...",
-            progress: true,
-            closable: false,
-        });
-        var nv = vertices.length;
+        var nv = vertices.length/3;
         var last = 0;
         var surf = new X.mesh();
         this.widgets.add({
@@ -207,17 +206,15 @@
         surf.ga = "TRIANGLES";
         p = surf.points;
         n = surf.normals;
-        Ext.each(vertices, function(vert, index, allVerts) {
-            if ((index - last) > ( nv / 100.0)) {
-                Ext.MessageBox.updateProgress(
-                        (index / nv),
-                        Math.round(100*index/nv) + '% completed');
-                last = index;
-            }
-            p.add(vert[0], vert[1], vert[2]);
-            n.add(normals[index][0], normals[index][1], normals[index][2]);
-        });
-        Ext.MessageBox.hide();
+
+        for (index = 0; index < nv; index = index + 1) {
+            p.add(vertices[index * 3 + 0],
+                  vertices[index * 3 + 1],
+                  vertices[index * 3 + 2]);
+            n.add(normals[index * 3 + 0],
+                  normals[index * 3 + 1],
+                  normals[index * 3 + 2]);
+        }
         surf.color = [1.0, 0.0, 0.0];
         this.renderer.add(surf);
         this.renderer.render();


diff -r ca054fb27326567f031a951948df74b9999758d7 -r b13dfdb47efd81bab25d9a0dde73784f51bfe89f yt/gui/reason/html/app/view/widgets/IsocontourCreator.js
--- a/yt/gui/reason/html/app/view/widgets/IsocontourCreator.js
+++ b/yt/gui/reason/html/app/view/widgets/IsocontourCreator.js
@@ -52,6 +52,7 @@
                 fieldLabel: 'Relative Value?',
                 itemId: 'relValue',
                 value: true,
+                checked: true,
                 width: 290,
                 allowBlank:false,
               },{


diff -r ca054fb27326567f031a951948df74b9999758d7 -r b13dfdb47efd81bab25d9a0dde73784f51bfe89f yt/gui/reason/widget_builders.py
--- a/yt/gui/reason/widget_builders.py
+++ b/yt/gui/reason/widget_builders.py
@@ -78,8 +78,8 @@
 def get_corners(pf, max_level=None):
     DL = pf.domain_left_edge[None,:,None]
     DW = pf.domain_width[None,:,None]/100.0
-    corners = ((pf.h.grid_corners-DL)/DW).tolist()
-    levels = pf.h.grid_levels.tolist()
+    corners = ((pf.h.grid_corners-DL)/DW)
+    levels = pf.h.grid_levels
     return corners, levels
 
 def get_isocontour(pf, field, value=None, rel_val = False):
@@ -88,7 +88,7 @@
     if value is None or rel_val:
         if value is None: value = 0.5
         mi, ma = na.log10(dd.quantities["Extrema"]("Density")[0])
-        value = 10.0**(value*(mi + ma))
+        value = 10.0**(value*(ma - mi) + mi)
     vert = dd.extract_isocontours("Density", value)
     na.multiply(vert, 100, vert)
     return vert


diff -r ca054fb27326567f031a951948df74b9999758d7 -r b13dfdb47efd81bab25d9a0dde73784f51bfe89f yt/gui/reason/widget_store.py
--- a/yt/gui/reason/widget_store.py
+++ b/yt/gui/reason/widget_store.py
@@ -242,13 +242,15 @@
             n = na.cross(vert[i*3,:], vert[i*3+1,:])
             normals[i*3:i*3+3,:] = n[None,:]
         ph.widget_payload(self, {'ptype':'isocontour',
-                                 'vert':vert.tolist(),
-                                 'normals':normals.tolist()})
+                                 'binary': ['vert', 'normals'],
+                                 'vert':vert,
+                                 'normals':normals})
 
     def deliver_gridlines(self):
         ph = PayloadHandler()
         corners, levels = get_corners(self.pf)
         ph.widget_payload(self, {'ptype':'grid_lines',
+                                 'binary': ['corners', 'levels'],
                                  'corners': corners,
                                  'levels': levels,
                                  'max_level': int(self.pf.h.max_level)})



https://bitbucket.org/yt_analysis/yt/changeset/bf59bb309709/
changeset:   bf59bb309709
branch:      yt
user:        MatthewTurk
date:        2012-06-24 03:26:35
summary:     Switching to using payloads for the data objects.
affected #:  2 files

diff -r 77ba5ce207656a2897ea24229e481648d94704ba -r bf59bb30970964996952ef55acd3a49d89f62ebb yt/gui/reason/html/app/controller/DataObjects.js
--- a/yt/gui/reason/html/app/controller/DataObjects.js
+++ b/yt/gui/reason/html/app/controller/DataObjects.js
@@ -45,7 +45,7 @@
 
     init: function() {
         this.application.addListener({
-           newdataobjects : {fn: this.refreshDataObjects, scope: this},
+           payloaddataobjects : {fn: this.refreshDataObjects, scope: this},
         });
         this.control({
             "#dataobjects": { itemcontextmenu:
@@ -57,8 +57,9 @@
         this.callParent(arguments);
     },
 
-    refreshDataObjects: function(objs) {
+    refreshDataObjects: function(payload) {
         /*console.log("Refreshing data objects");*/
+        var objs = payload['objs'];
         var root = this.getDataObjectsStore().getRootNode();
         root.removeAll();
         var pf;


diff -r 77ba5ce207656a2897ea24229e481648d94704ba -r bf59bb30970964996952ef55acd3a49d89f62ebb yt/gui/reason/html/app/controller/ServerCommunication.js
--- a/yt/gui/reason/html/app/controller/ServerCommunication.js
+++ b/yt/gui/reason/html/app/controller/ServerCommunication.js
@@ -49,9 +49,6 @@
         this.heartbeat = this.taskRunner.start(
             {run: this.heartbeatCall,
              interval: 250});
-        this.dataObjectBeat = this.taskRunner.start(
-            {run: this.dataObjectsCall,
-             interval: 5000});
         this.callParent(arguments);
     },
 
@@ -70,14 +67,6 @@
         this.application.fireEvent('payload' + payload['type'], payload);
     },
 
-    dataObjectsCall: function() {
-        yt_rpc.ExtDirectParameterFileList.get_list_of_pfs({}, 
-            function(f, a) {
-                if (f == null) { return; }
-                reason.fireEvent("newdataobjects", f);
-        });
-    },
-
     heartbeatCall: function() {
         if (heartbeatRequest == true) return;
         heartbeatRequest = true;



https://bitbucket.org/yt_analysis/yt/changeset/8fa22fea15f1/
changeset:   8fa22fea15f1
branch:      yt
user:        samskillman
date:        2012-06-24 03:27:57
summary:     Fixing a parenthesis
affected #:  1 file

diff -r b13dfdb47efd81bab25d9a0dde73784f51bfe89f -r 8fa22fea15f1c63744889b8f837ea5addef04cac yt/gui/reason/widget_store.py
--- a/yt/gui/reason/widget_store.py
+++ b/yt/gui/reason/widget_store.py
@@ -270,7 +270,7 @@
         centers = na.array([na.dot(na.eye(4)*R[3,2],na.dot(R, norm)) for R in views])
         r = views[0]
         print r 
-        ups = na.array([na.dot(R,up)) for R in views])
+        ups = na.array([na.dot(R,up) for R in views])
         print 'centers'
         for center in centers: print center
         print 'ups'



https://bitbucket.org/yt_analysis/yt/changeset/4ec769e8d76d/
changeset:   4ec769e8d76d
branch:      yt
user:        brittonsmith
date:        2012-06-24 01:26:27
summary:     Fixing pyro_queue script so it works.
affected #:  1 file

diff -r 16b7344e13f39d7209895d0552ea501273c9eaac -r 4ec769e8d76d38c3b1d2d98ef90790d6c780ca61 scripts/pyro_queue.py
--- a/scripts/pyro_queue.py
+++ b/scripts/pyro_queue.py
@@ -1,4 +1,12 @@
+import Pyro4
+import uuid
+
 from yt.mods import *
+from yt.utilities.parallel_tools.parallel_analysis_interface import \
+    _get_comm
+from yt.gui.reason.pyro_queue import \
+    PyroQueueRoot, \
+    PyroQueueNonRoot
 
 comm = _get_comm(())
 my_rank = comm.comm.rank



https://bitbucket.org/yt_analysis/yt/changeset/d60d2009de89/
changeset:   d60d2009de89
branch:      yt
user:        brittonsmith
date:        2012-06-24 01:28:29
summary:     Merged.
affected #:  2 files

diff -r 4ec769e8d76d38c3b1d2d98ef90790d6c780ca61 -r d60d2009de8990ef22705d6684915ec58cfb01d3 yt/gui/reason/html/js/functions.js
--- a/yt/gui/reason/html/js/functions.js
+++ /dev/null
@@ -1,687 +0,0 @@
-/**********************************************************************
-Functions for Reason
-
-Author: Cameron Hummels <chummels at gmail.com>
-Affiliation: Columbia
-Author: Jeffrey S. Oishi <jsoishi at gmail.com>
-Affiliation: KIPAC/SLAC/Stanford
-Author: Britton Smith <brittonsmith at gmail.com>
-Affiliation: MSU
-Author: Matthew Turk <matthewturk at gmail.com>
-Affiliation: Columbia University
-Homepage: http://yt-project.org/
-License:
-  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
-
-  This file is part of yt.
-
-  yt is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 3 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-***********************************************************************/
-
-function cell_finished(result) {
-    var new_log = false;
-    var cell_resulted = false;
-    var cell;
-    Ext.each(result, 
-    function(payload, index) {
-        if (payload['type'] == 'shutdown') {
-            reason.task_runner.stop(heartbeat);
-            reason.heartbeat_request = true;
-            return;
-        } else if (payload['type'] == 'cell_results') {
-            text = "<pre>"+payload['output']+"</pre>";
-            formatted_input = payload['input']
-            cell = new_cell(formatted_input, text, payload['raw_input']);
-            OutputContainer.add(cell);
-            OutputContainer.doLayout();
-            notebook.doLayout();
-            if (repl_input.locked == true) {
-                /* Assume only one locking level */
-                repl_input.locked = false;
-            } else {
-                repl_input.get("input_line").setValue("");
-            }
-            if (OutputContainer.items.length > 1) {
-                OutputContainer.body.dom.scrollTop = 
-                OutputContainer.body.dom.scrollHeight -
-                cell.body.dom.scrollHeight - 20;
-            }
-            cell_resulted = true;
-        } else if (payload['type'] == 'png_string') {
-            OutputContainer.add(new Ext.Panel({
-                autoEl:{
-                    tag:'img', 
-                    width:'25%',
-                    src:"data:image/png;base64," + payload['image_data'],
-                    id:"payload_image_" + number_images,
-                    onClick: "display_image('payload_image_" + number_images + "');"
-		        }
-            }));
-	        OutputContainer.doLayout();
-	        number_images++;
-        } else if (payload['type'] == 'cell_contents') {
-	        var input_line = repl_input.get("input_line");
-	        input_line.setValue(payload['value']);
-            repl_input.locked = true;
-        } else if (payload['type'] == 'log_entry') {
-            reason.log(payload['log_entry']);
-            new_log = true;
-        } else if (payload['type'] == 'widget') {
-            var widget_type = payload['widget_type'];
-            var widget = new widget_types[widget_type](payload['varname'],
-                                                       payload['data']);
-            widget_list[widget.id] = widget;
-            /*
-               Sometimes instantiating a widget adds some objects ...
-               Plus, often when creating a widget we disable the 
-               entry of data and whatnot. 
-            */
-            cell_resulted = true;
-        } else if (payload['type'] == 'widget_payload') {
-            var widget = widget_list[payload['widget_id']];
-            widget.accept_results(payload);
-        } else {
-            alert("Didn't know how to process " + payload['type']);
-        }
-    });
-    if (new_log == true){
-        reason.log_scroll()
-    }
-    if (cell_resulted == true) {
-        enable_input();
-    }
-}
-
-function display_image(image_id) {
-    var image = Ext.get(image_id);
-    var src = image.dom.src;
-    var virtualdom = '<html><title>Image Viewer</title><body><img src="' 
-        + src + '"/></body></html>',
-    prev = window.open('', 'image_viewer');
-    prev.document.open();
-    prev.document.write(virtualdom);
-    prev.document.close();
-}
-
-// Create a tree in the left panel with the pfs and their objects.
-function fill_tree(my_pfs) {
-    treePanel.root.removeAll();
-    Ext.each(my_pfs, function(pf, index) {
-        treePanel.root.appendChild(new Ext.tree.TreeNode({
-            text: pf.name,
-            objdata: {fn: pf.filename, varname: pf.varname, type: 'pf',
-                      field_list: pf.field_list},
-            leaf:false, 
-            expanded:true, 
-            iconCls: 'pf_icon'}));
-        this_pf = treePanel.root.lastChild
-        Ext.each(pf.objects, function(obj, obj_index) {
-            this_pf.appendChild(new Ext.tree.TreeNode(
-                {text: obj.name,
-                 leaf: true,
-                 iconCls: 'data_obj',
-                 objdata: {varname: obj.varname, type: 'obj',
-                           pfdata: this_pf.attributes.objdata},
-                 }));
-        });
-    });
-}
-
-function new_cell(input, result, raw_input) {
-    var name = "cell_" + cell_count;
-    var CellPanel = new Ext.Panel(
-        { 
-            id: name, 
-            //title: "Cell " + cell_count,
-            items: [
-                { xtype:'panel',
-                  layout: 'hbox',
-                  id:name+"_input",
-                  items: [
-                    { xtype:'panel',
-                      html:input,
-                      flex:1,
-                      boxMinHeight: 40,
-                    },
-                    { xtype: 'button',
-                      width: 24,
-                      height: 24,
-                      iconCls: 'upload',
-                      tooltip: 'Upload to Pastebin',
-                      listeners: {
-                          click: function(f, e) {
-                            yt_rpc.ExtDirectREPL.paste_text({to_paste:raw_input},
-                              function(f, a) {
-                                if (a.result['status'] == 'SUCCESS') {
-                                    var alert_text = 'Pasted cell to:<br>' + 
-                                    a.result['site']
-                                    var alert_text_rec = 'Pasted cell to: ' + 
-                                    a.result['site']
-                                    Ext.Msg.alert('Pastebin', alert_text);
-                                    var record = new logging_store.recordType(
-                                        {record: alert_text_rec });
-                                    logging_store.add(record, number_log_records++);
-                              }
-                            });
-                          }
-                        }
-                    },
-                    { xtype: 'button',
-                      width: 24,
-                      height: 24,
-                      iconCls: 'doubleuparrow',
-                      tooltip: 'Copy into current cell',
-                      listeners: {
-                          click: function(f, e) {
-                            repl_input.get('input_line').setValue(raw_input);
-                          }
-                      },
-                    },
-                  ],
-                },
-                { xtype:'panel',
-                  layout: 'hbox',
-                  items: [
-                    { xtype:'panel',
-                      id:name+"_result",
-                      autoScroll:true,
-                      flex: 1,
-                      html:result,
-                      boxMinHeight: 40,
-                    },
-                  ],
-                },
-            ]
-        }
-    );
-    cell_count++;
-    return CellPanel;
-}
-
-function getGridViewerHandler(node){
-function gridViewerHandler(item, pressed){
-    yt_rpc.ExtDirectREPL.create_grid_viewer(
-        {pfname:node.attributes.objdata.varname},
-        handle_result);
-}
-return gridViewerHandler;
-}
-
-function getGridDataViewerHandler(node){
-function gridDataViewerHandler(item, pressed){
-    yt_rpc.ExtDirectREPL.create_grid_dataview(
-        {pfname:node.attributes.objdata.varname},
-        handle_result);
-}
-return gridDataViewerHandler;
-}
-
-function getStreamlineViewerHandler(node){
-function streamlineViewerHandler(item, pressed){
-    yt_rpc.ExtDirectREPL.create_streamline_viewer(
-        {pfname:node.attributes.objdata.varname},
-        handle_result);
-}
-return streamlineViewerHandler;
-}
-
-function getIsocontourViewerHandler(node){
-function isocontourViewerHandler(item,pressed){
-    var win = new Ext.Window({
-        layout:'fit',
-        width:320,
-        height:250,
-        modal:true,
-        resizable:false,
-        draggable:false,
-        border:false,
-        title:'Isocontour Extraction in' + node,
-        items: [{
-            xtype: 'form', // FormPanel
-            labelWidth:80,
-            frame:true,
-            items: [{
-                xtype:'combo',
-                fieldLabel: 'Field',
-                id: 'field',
-                store:node.attributes.objdata.field_list,
-                width: 200,
-                allowBlank:false,
-                value: 'Density',
-                triggerAction: 'all',
-            },{
-                xtype:'combo',
-                fieldLabel: 'Sampling Field',
-                id: 'extract_field',
-                store:node.attributes.objdata.field_list,
-                width: 200,
-                allowBlank:false,
-                value: 'Temperature',
-                triggerAction: 'all',
-            },{
-                xtype:'textfield',
-                fieldLabel: 'Value',
-                id: 'value',
-                value: '1e-25',
-                width: 90,
-                allowBlank:false,
-            }],
-            buttons: [
-                {
-                    text: 'Extract',
-                    handler: function(b, e){
-                        var field = Ext.get("field").getValue();
-                        var value = Ext.get("value").getValue();
-                        var sampling_field = Ext.get("extract_field").getValue();
-                        yt_rpc.ExtDirectREPL.create_isocontours({
-                            pfname:node.attributes.objdata.varname,
-                            field:field, value:value,
-                            sampling_field:sampling_field},
-                          handle_result);
-                        disable_input();
-                        win.close();
-                    }
-                },{
-                    text: 'Cancel',
-                    handler: function(b, e){
-                        win.close();
-                    }
-                }
-            ]
-        }]
-    });
-    win.show(this);
-}
-return isocontourViewerHandler;
-}
-
-function getSliceHandler(node){
-function sliceHandler(item,pressed){
-    var win = new Ext.Window({
-        layout:'fit',
-        width:320,
-        height:250,
-        modal:true,
-        resizable:false,
-        draggable:false,
-        border:false,
-        title:'Slice Details for ' + node,
-        items: [{
-            xtype: 'form', // FormPanel
-            labelWidth:80,
-            frame:true,
-            items: [{
-                xtype:'textfield',
-                fieldLabel: 'Center X',
-                id: 'slice_x_center',
-                value: '0.5',
-                width: 90,
-                allowBlank:false,
-            },{
-                xtype:'textfield',
-                fieldLabel: 'Center Y',
-                id: 'slice_y_center',
-                value: '0.5',
-                width: 90,
-                allowBlank:false,
-            },{
-                xtype:'textfield',
-                fieldLabel: 'Center Z',
-                id: 'slice_z_center',
-                value: '0.5',
-                width: 90,
-                allowBlank:false,
-            },{
-                xtype:'combo',
-                fieldLabel: 'Axis',
-                id: 'slice_axis',
-                store:['X','Y','Z'],
-                width: 90,
-                allowBlank:false,
-                value: 'X',
-                triggerAction: 'all',
-            },{
-                xtype:'checkbox',
-                fieldLabel: 'Center on Max',
-                id: 'max_dens',
-                width: 90,
-                allowBlank:false,
-                handler: function(checkbox, checked) {
-                    if (checked == true) {
-                        this.ownerCt.get("slice_x_center").disable();
-                        this.ownerCt.get("slice_y_center").disable();
-                        this.ownerCt.get("slice_z_center").disable();
-                    } else {
-                        this.ownerCt.get("slice_x_center").enable();
-                        this.ownerCt.get("slice_y_center").enable();
-                        this.ownerCt.get("slice_z_center").enable();
-                    }
-                }
-            },{
-                xtype:'combo',
-                fieldLabel: 'Field',
-                id: 'slice_field',
-                store:node.attributes.objdata.field_list,
-                width: 200,
-                allowBlank:false,
-                value: 'Density',
-                triggerAction: 'all',
-            }],
-            buttons: [
-                {
-                    text: 'Slice',
-                    handler: function(b, e){
-                        var center = [Ext.get("slice_x_center").getValue(),
-                                      Ext.get("slice_y_center").getValue(),
-                                      Ext.get("slice_z_center").getValue()];
-                        var axis = Ext.get("slice_axis").getValue();
-                        var field = Ext.get("slice_field").getValue();
-                        var onmax = Ext.get("max_dens").getValue();
-                        yt_rpc.ExtDirectREPL.create_slice({
-                            pfname:node.attributes.objdata.varname,
-                            center: center, axis:axis, field:field, onmax:onmax},
-                          handle_result);
-                        disable_input();
-                        win.close();
-                    }
-                },{
-                    text: 'Cancel',
-                    handler: function(b, e){
-                        win.close();
-
-                    }
-                }
-            ]
-        }]
-    });
-    win.show(this);
-}
-return sliceHandler;
-}
-
-function widget_call(varname, method) {
-    var fcall = varname + "." + method;
-    yt_rpc.ExtDirectREPL.execute(
-        {code: fcall}, cell_finished);
-}
-
-function getPhasePlotHandler(node){
-function phasePlotHandler(item,pressed){
-    var win = new Ext.Window({
-        layout:'fit',
-        width:370,
-        height:220,
-        modal:true,
-        resizable:false,
-        draggable:false,
-        border:false,
-        title:'Phase Plot Details for ' + node,
-        items: [{
-            xtype: 'form', // FormPanel
-            labelWidth:80,
-            frame:true,
-            items: [ {
-                xtype:'combo',
-                fieldLabel: 'X Field',
-                id: 'x_field',
-                store:node.attributes.objdata.pfdata.field_list,
-                width: 230,
-                allowBlank:false,
-                triggerAction: 'all',
-                value: 'Density'
-            },{
-                xtype:'combo',
-                fieldLabel: 'Y Field',
-                id: 'y_field',
-                store:node.attributes.objdata.pfdata.field_list,
-                width: 230,
-                allowBlank:false,
-                triggerAction: 'all',
-                value: 'Temperature'
-            },{
-                xtype:'combo',
-                fieldLabel: 'Z Field',
-                id: 'z_field',
-                store:node.attributes.objdata.pfdata.field_list,
-                width: 230,
-                allowBlank:false,
-                triggerAction: 'all',
-                value: 'CellMassMsun'
-            },{
-                xtype:'combo',
-                fieldLabel: 'Weight Field',
-                id: 'weight',
-                store:['None'].concat(node.attributes.objdata.pfdata.field_list),
-                width: 230,
-                allowBlank:false,
-                triggerAction: 'all',
-                value: 'None'
-            }],
-            buttons: [
-                {
-                    text: 'Calculate',
-                    handler: function(b, e){
-                        var x_field = Ext.get("x_field").getValue();
-                        var y_field = Ext.get("y_field").getValue();
-                        var z_field = Ext.get("z_field").getValue();
-                        var weight = Ext.get("weight").getValue();
-                        yt_rpc.ExtDirectREPL.create_phase({
-                                objname: node.attributes.objdata.varname,
-                                /* Mirror image varnames ... */
-                                field_x: x_field,
-                                field_y: y_field,
-                                field_z: z_field,
-                                weight: weight,
-                                },
-                              handle_result);
-                        disable_input();
-                        win.close();
-                    }
-                },{
-                    text: 'Cancel',
-                    handler: function(b, e){win.close()}
-                }
-            ]
-        }]
-    });
-    win.show(this);
-}
-return phasePlotHandler;
-}
-
-function getProjectionHandler(node){
-function projectionHandler(item,pressed){
-    var win = new Ext.Window({
-        layout:'fit',
-        width:370,
-        height:220,
-        modal:true,
-        resizable:false,
-        draggable:false,
-        border:false,
-        title:'Projection Details for ' + node,
-        items: [{
-            xtype: 'form', // FormPanel
-            labelWidth:80,
-            frame:true,
-            items: [{
-                xtype:'combo',
-                fieldLabel: 'Axis',
-                id: 'axis',
-                store:['X','Y','Z'],
-                width: 90,
-                allowBlank:false,
-                triggerAction: 'all',
-                value: 'X',
-            },{
-                xtype:'checkbox',
-                fieldLabel: 'Center on Max',
-                id: 'max_dens',
-                width: 90,
-                allowBlank:false,
-                /* No handler, because no center */
-            },{
-                xtype:'combo',
-                fieldLabel: 'Field',
-                id: 'field',
-                store:node.attributes.objdata.field_list,
-                width: 230,
-                allowBlank:false,
-                triggerAction: 'all',
-                value: 'Density'
-            },{
-                xtype:'combo',
-                fieldLabel: 'Weight Field',
-                id: 'weightField',
-                store:['None'].concat(node.attributes.objdata.field_list),
-                width: 230,
-                allowBlank:false,
-                triggerAction: 'all',
-                value: 'None'
-            }],
-            buttons: [
-                {
-                    text: 'Project',
-                    handler: function(b, e){
-                        var axis = Ext.get("axis").getValue();
-                        var field = Ext.get("field").getValue();
-                        var weight = Ext.get("weightField").getValue();
-                        var onmax = Ext.get("max_dens").getValue();
-                        yt_rpc.ExtDirectREPL.create_proj({
-                                pfname: node.attributes.objdata.varname,
-                                axis: axis, field: field, weight: weight,
-                                onmax: onmax},
-                              handle_result);
-                        disable_input();
-                        win.close();
-                    }
-                },{
-                    text: 'Cancel',
-                    handler: function(b, e){win.close()}
-                }
-            ]
-        }]
-    });
-    win.show(this);
-}
-return projectionHandler;
-}
-
-function getSphereCreator(node){
-function sphereCreator(item,pressed){
-    var win = new Ext.Window({
-        layout:'fit',
-        width:320,
-        height:250,
-        modal:true,
-        resizable:false,
-        draggable:false,
-        border:false,
-        title:'Sphere Creator ' + node,
-        items: [{
-            xtype: 'form', // FormPanel
-            labelWidth:80,
-            frame:true,
-            items: [{
-                xtype:'textfield',
-                fieldLabel: 'Center X',
-                id: 'slice_x_center',
-                value: '0.5',
-                width: 90,
-                allowBlank:false,
-            },{
-                xtype:'textfield',
-                fieldLabel: 'Center Y',
-                id: 'slice_y_center',
-                value: '0.5',
-                width: 90,
-                allowBlank:false,
-            },{
-                xtype:'textfield',
-                fieldLabel: 'Center Z',
-                id: 'slice_z_center',
-                value: '0.5',
-                width: 90,
-                allowBlank:false,
-            },{
-                xtype:'textfield',
-                fieldLabel: 'Radius',
-                id: 'radius_value',
-                value: '0.5',
-                width: 90,
-                allowBlank:false,
-            },{
-                xtype:'combo',
-                fieldLabel: 'Unit',
-                id: 'radius_unit',
-                store:['unitary', '1', 'mpc', 'kpc', 'pc', 'au', 'rsun', 'cm'],
-                width: 90,
-                allowBlank:false,
-                value: 'Unitary',
-                triggerAction: 'all',
-            },{
-                xtype:'checkbox',
-                fieldLabel: 'Center on Max',
-                id: 'max_dens',
-                width: 90,
-                allowBlank:false,
-                handler: function(checkbox, checked) {
-                    if (checked == true) {
-                        this.ownerCt.get("slice_x_center").disable();
-                        this.ownerCt.get("slice_y_center").disable();
-                        this.ownerCt.get("slice_z_center").disable();
-                    } else {
-                        this.ownerCt.get("slice_x_center").enable();
-                        this.ownerCt.get("slice_y_center").enable();
-                        this.ownerCt.get("slice_z_center").enable();
-                    }
-                }
-            }],
-            buttons: [
-                {
-                    text: 'Slice',
-                    handler: function(b, e){
-                        var center = [Ext.get("slice_x_center").getValue(),
-                                      Ext.get("slice_y_center").getValue(),
-                                      Ext.get("slice_z_center").getValue()];
-                        var onmax = Ext.get("max_dens").getValue();
-                        var radius = [Ext.get("radius_value").getValue(),
-                                      Ext.get("radius_unit").getValue()]
-                        objargs = {radius: radius}
-                        if (onmax == true) {
-                            objargs['center'] = 'max';
-                        } else {
-                            objargs['center'] = center;
-                        }
-                        yt_rpc.ExtDirectREPL.object_creator({
-                            pfname:node.attributes.objdata.varname,
-                            objtype:'sphere', objargs:objargs},
-                          handle_result);
-                        disable_input();
-                        win.close();
-                    }
-                },{
-                    text: 'Cancel',
-                    handler: function(b, e){
-                        win.close();
-
-                    }
-                }
-            ]
-        }]
-    });
-    win.show(this);
-}
-return sphereCreator;
-}


diff -r 4ec769e8d76d38c3b1d2d98ef90790d6c780ca61 -r d60d2009de8990ef22705d6684915ec58cfb01d3 yt/gui/reason/html/js/reason.js
--- a/yt/gui/reason/html/js/reason.js
+++ /dev/null
@@ -1,383 +0,0 @@
-/**********************************************************************
-The main GUI facility for Reason
-
-Author: Cameron Hummels <chummels at gmail.com>
-Affiliation: Columbia
-Author: Jeffrey S. Oishi <jsoishi at gmail.com>
-Affiliation: KIPAC/SLAC/Stanford
-Author: Britton Smith <brittonsmith at gmail.com>
-Affiliation: MSU
-Author: Matthew Turk <matthewturk at gmail.com>
-Affiliation: Columbia University
-Homepage: http://yt-project.org/
-License:
-  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
-
-  This file is part of yt.
-
-  yt is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 3 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-***********************************************************************/
-
-Ext.app.Module = function(config){
-    Ext.apply(this, config);
-    Ext.app.Module.superclass.constructor.call(this);
-    this.init();
-}
-
-Ext.extend(Ext.app.Module, Ext.util.Observable, {
-    init : Ext.emptyFn
-});
-
-Reason = new Ext.app.App({
-  init: function() {
-    if (typeof(console) != "undefined") {
-        console.log('Mitchell!\nPardon me! Mitchell!')
-    }
-    this.setup_viewport();
-    // Go ahead and create the TreePanel now so that we can use it below
-    // get a reference to the HTML element with id "hideit" and add a click listener to it 
-    Ext.get("hideit").on('click', function(){
-        // get a reference to the Panel that was created with id = 'west-panel' 
-	    var w = Ext.getCmp('west-panel');
-        // expand or collapse that Panel based on its collapsed property state
-        // need to make room for six sour cream burritos
-        w.collapsed ? w.expand() : w.collapse();
-    });
-
-    /* Now we create our record store. */
-    this.logging_store = new Ext.data.Store({
-        fields: [{name:'record'}],
-        reader: new Ext.data.ArrayReader({}, [{name: 'record'}]),
-    });
-
-    this.widget_types = {}
-    this.widget_list = {}
-    this.number_log_records = 0;
-    this.number_images = 0;
-    this.cell_count = 0;
-    this.notebook = viewport.get("center-panel").get("notebook");
-    this.status_region = viewport.get("status-region");
-  },
-
-  setup_viewport: function() {
-    this.viewport = new Ext.Viewport({
-        layout: 'border',
-        items: [
-		// lazily created panel (xtype:'panel' is default)
-            {
-                xtype: 'grid',
-                store: logging_store,
-                defaults: { width: 800 },
-                columns: [ {id:'record', 
-                    sortable: false,
-                    width:800} ],
-                autofill: true,
-                region: 'south',
-                id: "status-region",
-                cls: "status-logger",
-                split: true,
-                height: 100,
-                maxSize: 200,
-                collapsible: true,
-                title: 'Status',
-                margins: '0 0 0 0',
-            }, {
-                region: 'west',
-                id: 'west-panel', // see Ext.getCmp() below
-                title: 'Data Objects',
-                split: true,
-                width: 200,
-                minSize: 175,
-                maxSize: 400,
-                collapsible: true,
-                margins: '0 0 0 5',
-                layout: {
-                    type: 'anchor',
-                },
-                items: [{
-                        xtype: 'toolbar',
-                        items: [ main_menu ],
-                    },
-                    treePanel,
-                ]
-		  // in this instance the TabPanel is not wrapped by another panel
-		  // since no title is needed, this Panel is added directly
-		  // as a Container
-            },{
-                xtype: 'tabpanel',
-                region: 'center', 
-                id: 'center-panel',
-                deferredRender: false,
-                activeTab: 0,     
-                items: [{
-                        title: 'YT',
-                        id: 'notebook',
-                        layout: 'vbox',
-                        layoutConfig: {align:'stretch'},
-                        closable: false,
-                        autoScroll: false,
-                        iconCls: 'console',
-                        items: [InputContainer, OutputContainer]
-                    }, 
-                ]
-            }
-        ]
-    });
-  },
-
-  log : function(text) {
-    this.logging_store.add({record:text}, this.number_log_records++);
-  },
-
-  log_scroll : function() {
-    this.status_region.getView().focusRow(number_log_records-1);
-  },
-
-  handle_result : function(f, a) {
-    if(a.status == false){
-        Ext.Msg.alert("Error", "Something has gone wrong.");
-        examine = {f: f, a: a};
-        return;
-    }
-    this.cell_finished(a.result);
-  },
-
-  start_heartbeat : function() {
-    this.task_runner = new Ext.util.TaskRunner();
-    this.heartbeat_request = false;
-    this.number_heartbeats = 0;
-    this.heartbeat = {
-    run:
-      function(){ if (this.heartbeat_request == true) return; 
-        this.heartbeat_request = true;
-        yt_rpc.ExtDirectREPL.heartbeat(
-            {}, function(f, a) {
-            this.heartbeat_request = false;
-            if (f != null) {
-                handle_result(f, a);
-            }})},
-    interval: 250};
-
-    this.task_runner.start(heartbeat);
-  },
-
-  enable_input : function() {
-    repl_input.body.removeClass("cell_waiting");
-    repl_input.get('input_line').setReadOnly(false);
-    repl_input.get("input_line").focus();
-    yt_rpc.ExtDirectParameterFileList.get_list_of_pfs({}, fill_tree);
-  },
-
-  disable_input : function() {
-    this.InputCell.get('input_line').setReadOnly(true);
-    this.InputCell.body.addClass("cell_waiting");
-  },
-});
-
-Reason.Interpreter = function() { 
-    var interpreter = this;
-    this.execute = function() {
-        this.disable_input();
-        yt_rpc.ExtDirectREPL.execute({
-            code:this.InputForm.get('input_line').getValue()},
-        this.handle_result);
-    };
-    this.get_contents() {
-        return this.InputForm.get('input_line').getValue();
-    }
-    this.set_contents(contents, focus) {
-        this.InputForm.get('input_line').setValue(contents);
-        if (focus == true) {
-            this.InputForm.get('input_line').focus();
-        }
-    }
-    this.InputForm = new Ext.FormPanel({
-        title: 'YT Input',
-        url: 'push',
-        flex: 0.2,
-        layout: 'fit',
-        padding: 5,
-        height: '100%',
-        flex: 1.0,
-        items: [{
-            id: 'input_line',
-            xtype: 'textarea',
-            width: '100%',
-            autoScroll: true,
-            name: 'line',
-            allowBlank: 'True',
-            bodyStyle: 'font-family: "monospace";',
-            listeners: {
-                specialkey: function(f, e){
-                    if (e.getKey() == e.ENTER) {
-                        Reason.Interpreter.execute();
-                    }
-                },
-                afterrender: function(f, e){
-                    //var input_line_drop_target_el = repl_input.get("input_line").el.dom;
-                    var input_line_drop_target_el = repl_input.body.dom;
-
-                    var input_line_drop_target = new Ext.dd.DropTarget(input_line_drop_target_el, {
-                        ddGroup     : 'pfDDgroup',
-                        notifyEnter : function(ddSource, e, data) {
-                            repl_input.body.stopFx();
-                            repl_input.body.highlight();
-                        },
-                        notifyDrop  : function(ddSource, e, data){
-
-                            var varname = data.node.attributes.objdata.varname;
-                            /* There is possibly a better way to do this, where it's also inserted correctly. */
-                            var line = Reason.Interpreter.get_contents();
-                            Reason.interpreter.set_contents(line + varname, true);
-                            return(true);
-                        }
-                    });
-                },
-            },
-        },],
-    });
-    this.InputContainer = new Ext.Panel({
-        title: 'YT Input',
-        flex: 0.3,
-        layout: {type: 'hbox',
-                 pack: 'start',
-                 align: 'stretch',
-                 },
-        items: [ interpreter.InputForm,
-                { xtype: 'button',
-                  width: 24,
-                  height: 24,
-                  iconCls: 'doubledownarrow',
-                  tooltip: 'Execute Cell',
-                  listeners: {
-                      click: function(f, e) { interpreter.execute(); }
-                  },
-                }
-               ]
-    });
-
-
-var OutputContainer = new Ext.Panel({
-    title: 'YT Output',
-    id: 'output_container',
-    autoScroll: true,
-    flex: 0.8,
-    items: []
-});
-
-TreePanel = function(
-new Ext.tree.TreePanel({
-    iconCls: 'nav',
-    id: 'tree-panel',
-    layout: 'anchor',
-    region:'west',
-    split: true,
-    anchor: '100% -35',
-    minSize: 150,
-    autoScroll: true,
-    rootVisible: false,
-    ddGroup: 'pfDDgroup',
-    enableDD: true,
-    root:new Ext.tree.TreeNode({
-        expanded:true,
-        leaf:false,
-        text:''
-    }),
-    listeners: {
-        render: {
-            fn: function() {
-                Ext.getBody().on("contextmenu", Ext.emptyFn,
-                null, {preventDefault: true});
-            }
-        },
-        dblclick: {
-            fn: function(node, e) {
-                treePanel.fireEvent("contextmenu", node, e);
-            }
-        },
-        contextmenu: {
-            fn: function(node, event){
-                var rightclickMenu;
-                if (node.attributes.objdata.type == 'obj') {
-                  rightClickMenu = new Ext.menu.Menu({
-                      items: [
-                          {
-                              text: 'Phase Plot',
-                              handler: getPhasePlotHandler(node),
-                          }, 
-                      ]
-                  });
-                } else if (node.attributes.objdata.type == 'pf') {
-                  rightClickMenu = new Ext.menu.Menu({
-                      items: [
-                          {
-                              text: 'View Grids',
-                              handler: getGridViewerHandler(node),
-                          }, {
-                              text: 'View Isocontour',
-                              handler: getIsocontourViewerHandler(node),
-                          }, {
-                              text: 'View Grid Data',
-                              handler: getGridDataViewerHandler(node),
-                          }, {
-                              text: 'Open slice',
-                              handler: getSliceHandler(node),
-                          }, {
-                              text: 'Open projection',
-                              handler: getProjectionHandler(node),
-                          /*}, {
-                              text: 'Create Sphere',
-                              handler: getSphereCreator(node), */
-                          }, /*{
-                              text: 'View Streamlines',
-                              handler: getStreamlineViewerHandler(node),
-                          }, */
-                      ]
-                  });
-                }
-                rightClickMenu.showAt(event.xy);
-            }
-        }
-    }
-});
-
-var reason;
-var examine;
-
-Ext.onReady(function(){
-    Ext.BLANK_IMAGE_URL = 'resources/resources/images/default/s.gif';
-
-    // NOTE: This is an example showing simple state management. During development,
-    // it is generally best to disable state management as dynamically-generated ids
-    // can change across page loads, leading to unpredictable results.  The developer
-    // should ensure that stable state ids are set for stateful components in real apps.
-    // it's a cold day for pontooning.
-    Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
-    reason = Reason()
-    reason.log('Welcome to yt.');
-    reason.log('After entering a line of code in the YT Input field, press shift-enter to evaluate.');
-    reason.log('4d3d3d3 engaged.');
-
-    if (!Ext.state.Manager.get("reason_welcomed", false)) {
-        Ext.MessageBox.alert("Reason v0.5",
-        "Welcome to Reason.  <br>Treat the 'YT Input' field as a YT/python intepreter.<br>Press shift-enter to evaluate.",
-        function(b,e){ repl_input.get("input_line").focus(); });
-        Ext.state.Manager.set("reason_welcomed", true);
-    } else { 
-        repl_input.get("input_line").focus();
-    }
-
-    /* Set up the heartbeat */
-    reason.start_heartbeat();
-});



https://bitbucket.org/yt_analysis/yt/changeset/ace96398f849/
changeset:   ace96398f849
branch:      yt
user:        brittonsmith
date:        2012-06-24 03:30:25
summary:     Now using payloads and getting list of datasets.
affected #:  3 files

diff -r d60d2009de8990ef22705d6684915ec58cfb01d3 -r ace96398f8498a9bcab57af0cd145b074952f8ac yt/gui/reason/extdirect_repl.py
--- a/yt/gui/reason/extdirect_repl.py
+++ b/yt/gui/reason/extdirect_repl.py
@@ -458,36 +458,6 @@
             results.append((os.path.basename(fn), size, t))
         return dict(objs = results, cur_dir=cur_dir)
 
-class ExtDirectParameterFileList(BottleDirectRouter):
-    my_name = "ExtDirectParameterFileList"
-    api_url = "pflist"
-
-    def get_list_of_pfs(self):
-        # Note that this instantiates the hierarchy.  This can be a costly
-        # event.  However, we're going to assume that it's okay, if you have
-        # decided to load up the parameter file.
-        from yt.data_objects.static_output import _cached_pfs
-        rv = []
-        for fn, pf in sorted(_cached_pfs.items()):
-            objs = []
-            pf_varname = "_cached_pfs['%s']" % (fn)
-            field_list = []
-            if pf._instantiated_hierarchy is not None: 
-                field_list = list(set(pf.h.field_list + pf.h.derived_field_list))
-                field_list = [dict(text = f) for f in sorted(field_list)]
-                for i,obj in enumerate(pf.h.objects):
-                    try:
-                        name = str(obj)
-                    except ReferenceError:
-                        continue
-                    objs.append(dict(name=name, type=obj._type_name,
-                                     filename = '', field_list = [],
-                                     varname = "%s.h.objects[%s]" % (pf_varname, i)))
-            rv.append( dict(name = str(pf), children = objs, filename=fn,
-                            type = "parameter_file",
-                            varname = pf_varname, field_list = field_list) )
-        return rv
-
 class PayloadLoggingHandler(logging.StreamHandler):
     def __init__(self, *args, **kwargs):
         logging.StreamHandler.__init__(self, *args, **kwargs)


diff -r d60d2009de8990ef22705d6684915ec58cfb01d3 -r ace96398f8498a9bcab57af0cd145b074952f8ac yt/gui/reason/pyro_queue.py
--- a/yt/gui/reason/pyro_queue.py
+++ b/yt/gui/reason/pyro_queue.py
@@ -1,5 +1,5 @@
 """
-Task queue to connect with reason via Pyro4.
+Task queue for reason.
 
 Author: Britton Smith <brittonsmith at gmail.com>
 Affiliation: Michigan State University
@@ -26,13 +26,12 @@
 """
 
 import numpy as na
-import Pyro4
-import uuid
 
 from yt.funcs import *
 
 from yt.gui.reason.basic_repl import ProgrammaticREPL
 from yt.gui.reason.bottle_mods import PayloadHandler
+from .utils import get_list_of_datasets
 
 class PyroQueueRoot(object):
     def __init__(self, comm):
@@ -44,7 +43,9 @@
         mylog.info('Root sending out code.')
         code = self.comm.comm.bcast(code, root=0)
         value = self.repl.execute(code)
-        return value
+        datasets = get_list_of_datasets()
+        self.payload_handler.add_payload({'type': 'payloaddataobjects',
+                                          'objs': datasets})
 
     def deliver(self):
         return self.payload_handler.deliver_payloads()


diff -r d60d2009de8990ef22705d6684915ec58cfb01d3 -r ace96398f8498a9bcab57af0cd145b074952f8ac yt/gui/reason/utils.py
--- a/yt/gui/reason/utils.py
+++ b/yt/gui/reason/utils.py
@@ -53,3 +53,28 @@
                'image_data':img_data}
     ph.add_payload(payload)
 
+def get_list_of_datasets():
+    # Note that this instantiates the hierarchy.  This can be a costly
+    # event.  However, we're going to assume that it's okay, if you have
+    # decided to load up the parameter file.
+    from yt.data_objects.static_output import _cached_pfs
+    rv = []
+    for fn, pf in sorted(_cached_pfs.items()):
+        objs = []
+        pf_varname = "_cached_pfs['%s']" % (fn)
+        field_list = []
+        if pf._instantiated_hierarchy is not None: 
+            field_list = list(set(pf.h.field_list + pf.h.derived_field_list))
+            field_list = [dict(text = f) for f in sorted(field_list)]
+            for i,obj in enumerate(pf.h.objects):
+                try:
+                    name = str(obj)
+                except ReferenceError:
+                    continue
+                objs.append(dict(name=name, type=obj._type_name,
+                                 filename = '', field_list = [],
+                                 varname = "%s.h.objects[%s]" % (pf_varname, i)))
+        rv.append( dict(name = str(pf), children = objs, filename=fn,
+                        type = "parameter_file",
+                        varname = pf_varname, field_list = field_list) )
+    return rv



https://bitbucket.org/yt_analysis/yt/changeset/32ce5d4253a3/
changeset:   32ce5d4253a3
branch:      yt
user:        brittonsmith
date:        2012-06-24 03:30:53
summary:     Merged.
affected #:  2 files

diff -r ace96398f8498a9bcab57af0cd145b074952f8ac -r 32ce5d4253a36da8fb0b3910d42dd3e0b895253f yt/gui/reason/html/app/controller/DataObjects.js
--- a/yt/gui/reason/html/app/controller/DataObjects.js
+++ b/yt/gui/reason/html/app/controller/DataObjects.js
@@ -45,7 +45,7 @@
 
     init: function() {
         this.application.addListener({
-           newdataobjects : {fn: this.refreshDataObjects, scope: this},
+           payloaddataobjects : {fn: this.refreshDataObjects, scope: this},
         });
         this.control({
             "#dataobjects": { itemcontextmenu:
@@ -57,8 +57,9 @@
         this.callParent(arguments);
     },
 
-    refreshDataObjects: function(objs) {
+    refreshDataObjects: function(payload) {
         /*console.log("Refreshing data objects");*/
+        var objs = payload['objs'];
         var root = this.getDataObjectsStore().getRootNode();
         root.removeAll();
         var pf;


diff -r ace96398f8498a9bcab57af0cd145b074952f8ac -r 32ce5d4253a36da8fb0b3910d42dd3e0b895253f yt/gui/reason/html/app/controller/ServerCommunication.js
--- a/yt/gui/reason/html/app/controller/ServerCommunication.js
+++ b/yt/gui/reason/html/app/controller/ServerCommunication.js
@@ -49,9 +49,6 @@
         this.heartbeat = this.taskRunner.start(
             {run: this.heartbeatCall,
              interval: 250});
-        this.dataObjectBeat = this.taskRunner.start(
-            {run: this.dataObjectsCall,
-             interval: 5000});
         this.callParent(arguments);
     },
 
@@ -70,14 +67,6 @@
         this.application.fireEvent('payload' + payload['type'], payload);
     },
 
-    dataObjectsCall: function() {
-        yt_rpc.ExtDirectParameterFileList.get_list_of_pfs({}, 
-            function(f, a) {
-                if (f == null) { return; }
-                reason.fireEvent("newdataobjects", f);
-        });
-    },
-
     heartbeatCall: function() {
         if (heartbeatRequest == true) return;
         heartbeatRequest = true;



https://bitbucket.org/yt_analysis/yt/changeset/8339797f4778/
changeset:   8339797f4778
branch:      yt
user:        brittonsmith
date:        2012-06-24 03:32:26
summary:     Putting a return back.
affected #:  1 file

diff -r 32ce5d4253a36da8fb0b3910d42dd3e0b895253f -r 8339797f477891b2889a534b9f7bd50123311d9c yt/gui/reason/pyro_queue.py
--- a/yt/gui/reason/pyro_queue.py
+++ b/yt/gui/reason/pyro_queue.py
@@ -46,6 +46,7 @@
         datasets = get_list_of_datasets()
         self.payload_handler.add_payload({'type': 'payloaddataobjects',
                                           'objs': datasets})
+        return value
 
     def deliver(self):
         return self.payload_handler.deliver_payloads()



https://bitbucket.org/yt_analysis/yt/changeset/592a3249e898/
changeset:   592a3249e898
branch:      yt
user:        brittonsmith
date:        2012-06-24 03:38:16
summary:     Removed pflist.
affected #:  2 files

diff -r 8339797f477891b2889a534b9f7bd50123311d9c -r 592a3249e8984775150fbe557151288bb16fd944 yt/gui/reason/extdirect_repl.py
--- a/yt/gui/reason/extdirect_repl.py
+++ b/yt/gui/reason/extdirect_repl.py
@@ -240,7 +240,6 @@
         # This has to be routed to the root directory
         self.api_url = "repl"
         BottleDirectRouter.__init__(self)
-        self.pflist = ExtDirectParameterFileList()
         self.executed_cell_texts = []
         self.payload_handler = PayloadHandler()
         if use_pyro:


diff -r 8339797f477891b2889a534b9f7bd50123311d9c -r 592a3249e8984775150fbe557151288bb16fd944 yt/gui/reason/html/index.html
--- a/yt/gui/reason/html/index.html
+++ b/yt/gui/reason/html/index.html
@@ -16,7 +16,6 @@
     <script type="text/javascript" src="resources/extjs-4.1.0/ext-all-debug.js"></script><script type="text/javascript" src="reason/app.js"></script><script type="text/javascript" src="ext-repl-api.js"></script>
-    <script type="text/javascript" src="resources/ext-pflist-api.js"></script><!-- Additional Ext UX files --><script type="text/javascript" src="reason/resources/ux/CheckColumn.js"></script>



https://bitbucket.org/yt_analysis/yt/changeset/c38c0acfcdc5/
changeset:   c38c0acfcdc5
branch:      yt
user:        MatthewTurk
date:        2012-06-24 03:46:52
summary:     Fixing data object payload delivery
affected #:  4 files

diff -r 592a3249e8984775150fbe557151288bb16fd944 -r c38c0acfcdc569644db232bbd23ecbe73418d4e0 yt/gui/reason/extdirect_repl.py
--- a/yt/gui/reason/extdirect_repl.py
+++ b/yt/gui/reason/extdirect_repl.py
@@ -54,6 +54,7 @@
 from .bottle_mods import preroute, BottleDirectRouter, notify_route, \
                          PayloadHandler, lockit
 from yt.utilities.bottle import response, request, route, static_file
+from .utils import get_list_of_datasets
 from .basic_repl import ProgrammaticREPL
 
 try:
@@ -122,6 +123,10 @@
                  'input': highlighter(code),
                  'raw_input': code},
                 )
+        objs = get_list_of_datasets()
+        self.repl.payload_handler.add_payload(
+            {'type': 'dataobjects',
+             'objs': objs})
 
 class PyroExecutionThread(ExecutionThread):
     def __init__(self, repl):


diff -r 592a3249e8984775150fbe557151288bb16fd944 -r c38c0acfcdc569644db232bbd23ecbe73418d4e0 yt/gui/reason/html/app/controller/Notebook.js
--- a/yt/gui/reason/html/app/controller/Notebook.js
+++ b/yt/gui/reason/html/app/controller/Notebook.js
@@ -106,7 +106,6 @@
     allowInput: function() {
         this.getInputLine().removeCls("cell_waiting");
         this.getInputLine().setReadOnly(false);
-        console.log("Calling FileList");
         var application = this.application;
     },
 


diff -r 592a3249e8984775150fbe557151288bb16fd944 -r c38c0acfcdc569644db232bbd23ecbe73418d4e0 yt/gui/reason/html/app/controller/ServerCommunication.js
--- a/yt/gui/reason/html/app/controller/ServerCommunication.js
+++ b/yt/gui/reason/html/app/controller/ServerCommunication.js
@@ -70,7 +70,7 @@
     heartbeatCall: function() {
         if (heartbeatRequest == true) return;
         heartbeatRequest = true;
-        console.log("Sending heartbeat");
+        /*console.log("Sending heartbeat");*/
         yt_rpc.ExtDirectREPL.heartbeat(
             {}, function(f, a) {
                 heartbeatRequest = false;


diff -r 592a3249e8984775150fbe557151288bb16fd944 -r c38c0acfcdc569644db232bbd23ecbe73418d4e0 yt/gui/reason/pyro_queue.py
--- a/yt/gui/reason/pyro_queue.py
+++ b/yt/gui/reason/pyro_queue.py
@@ -44,7 +44,7 @@
         code = self.comm.comm.bcast(code, root=0)
         value = self.repl.execute(code)
         datasets = get_list_of_datasets()
-        self.payload_handler.add_payload({'type': 'payloaddataobjects',
+        self.payload_handler.add_payload({'type': 'dataobjects',
                                           'objs': datasets})
         return value
 



https://bitbucket.org/yt_analysis/yt/changeset/3bad7bdebdb1/
changeset:   3bad7bdebdb1
branch:      yt
user:        MatthewTurk
date:        2012-06-24 03:53:45
summary:     Merging from the Scene work
affected #:  11 files

diff -r c38c0acfcdc569644db232bbd23ecbe73418d4e0 -r 3bad7bdebdb1fa06754f27697ac31b2b79880c6d yt/data_objects/data_containers.py
--- a/yt/data_objects/data_containers.py
+++ b/yt/data_objects/data_containers.py
@@ -2634,13 +2634,16 @@
         """
         verts = []
         samples = []
+        pb = get_pbar("Extracting ", len(list(self._get_grid_objs())))
         for i, g in enumerate(self._get_grid_objs()):
+            pb.update(i)
             my_verts = self._extract_isocontours_from_grid(
                             g, field, value, sample_values)
             if sample_values is not None:
                 my_verts, svals = my_verts
                 samples.append(svals)
             verts.append(my_verts)
+        pb.finish()
         verts = na.concatenate(verts).transpose()
         verts = self.comm.par_combine_object(verts, op='cat', datatype='array')
         verts = verts.transpose()


diff -r c38c0acfcdc569644db232bbd23ecbe73418d4e0 -r 3bad7bdebdb1fa06754f27697ac31b2b79880c6d yt/gui/reason/bottle_mods.py
--- a/yt/gui/reason/bottle_mods.py
+++ b/yt/gui/reason/bottle_mods.py
@@ -24,16 +24,18 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """
 
+import uuid
+import json
+import logging, threading
+import sys
+import urllib, urllib2
+import numpy as na
+
 from yt.utilities.bottle import \
     server_names, debug, route, run, request, ServerAdapter, response
-import uuid
 from extdirect_router import DirectRouter, DirectProviderDefinition
-import json
-import logging, threading
 from yt.utilities.logger import ytLogger as mylog
 from yt.funcs import *
-import sys
-import urllib, urllib2
 
 route_functions = {}
 route_watchers = []
@@ -48,9 +50,30 @@
 def notify_route(watcher):
     route_watchers.append(watcher)
 
+class BinaryDelivery(object):
+    delivered = False
+    payload = ""
+    def __init__(self, payload, name = ""):
+        self.name = name
+        self.payload = payload
+        #sys.__stderr__.write("CREATING A BINARY PAYLOAD %s (%s)\n" % (
+        #    self.name, len(self.payload)))
+
+    def get(self):
+        # We set our 
+        #sys.__stderr__.write("REQUESTED A BINARY PAYLOAD %s (%s)\n" % (
+        #    self.name, len(self.payload)))
+        p = self.payload
+        if p == "":
+            response.status = 404
+            return
+        self.payload = ""
+        return p
+
 class PayloadHandler(object):
     _shared_state = {}
     payloads = None
+    binary_payloads = None
     recorded_payloads = None
     multicast_ids = None
     multicast_payloads = None
@@ -59,6 +82,7 @@
     event = None
     count = 0
     debug = False
+    _prefix = ""
 
     def __new__(cls, *p, **k):
         self = object.__new__(cls, *p, **k)
@@ -72,6 +96,7 @@
         if self.event is None: self.event = threading.Event()
         if self.multicast_payloads is None: self.multicast_payloads = {}
         if self.multicast_ids is None: self.multicast_ids = {}
+        if self.binary_payloads is None: self.binary_payloads = []
 
     def deliver_payloads(self):
         with self.lock:
@@ -92,6 +117,8 @@
 
     def add_payload(self, to_add):
         with self.lock:
+            if "binary" in to_add:
+                self._add_binary_payload(to_add)
             self.payloads.append(to_add)
             # Does this next part need to be in the lock?
             if to_add.get("widget_id", None) in self.multicast_ids:
@@ -101,6 +128,23 @@
             if self.debug:
                 sys.__stderr__.write("**** Adding payload of type %s\n" % (to_add['type']))
 
+    def _add_binary_payload(self, bp):  
+        # This shouldn't be called by anybody other than add_payload.
+        bkeys = ensure_list(bp['binary'])
+        bp['binary'] = []
+        for bkey in bkeys:
+            bdata = bp.pop(bkey) # Get the binary data
+            if isinstance(bdata, na.ndarray):
+                bdata = bdata.tostring()
+            bpserver = BinaryDelivery(bdata, bkey)
+            self.binary_payloads.append(bpserver)
+            uu = uuid.uuid4().hex
+            bp['binary'].append((bkey, uu))
+            route("%s/%s" % (self._prefix, uu))(bpserver.get)
+            if self.debug:
+                sys.__stderr__.write(
+                    "**** Adding binary payload (%s) to %s\n" % (bkey, uu))
+
     def replay_payloads(self):
         return self.recorded_payloads
 


diff -r c38c0acfcdc569644db232bbd23ecbe73418d4e0 -r 3bad7bdebdb1fa06754f27697ac31b2b79880c6d yt/gui/reason/extdirect_repl.py
--- a/yt/gui/reason/extdirect_repl.py
+++ b/yt/gui/reason/extdirect_repl.py
@@ -259,6 +259,7 @@
         reason_pylab()
 
     def activate(self):
+        self.payload_handler._prefix = self._global_token
         self._setup_logging_handlers()
         # Setup our heartbeat
         self.last_heartbeat = time.time()


diff -r c38c0acfcdc569644db232bbd23ecbe73418d4e0 -r 3bad7bdebdb1fa06754f27697ac31b2b79880c6d yt/gui/reason/html/app/controller/WidgetDirector.js
--- a/yt/gui/reason/html/app/controller/WidgetDirector.js
+++ b/yt/gui/reason/html/app/controller/WidgetDirector.js
@@ -134,10 +134,46 @@
         }
         /*console.log("Directing payload for " + payload['widget_id'] +
                     " to resultId " + resultId);*/
+        if (payload['binary'] != null) {
+            this.loadBinaryData(payload);
+            return;
+        }
         var widgetInfo = this.getWidgetInstancesStore().getAt(resultId).data;
         widgetInfo['widget'].applyPayload(payload);
     },
 
+    loadBinaryData: function(payload1) {
+        /* https://developer.mozilla.org/en/using_xmlhttprequest
+           including progress */
+        function loadBinaryPayload(payload) {
+            var req = new XMLHttpRequest();
+            var bkeys = payload['binary'];
+            var nLeft = bkeys.length;
+            var bkey = bkeys[nLeft - 1];
+            var director = this;
+            payload['binary'] = null;
+            req.open("GET", bkey[1], true);
+            req.responseType = "arraybuffer";
+            onLoad = function(e) {
+                payload[bkey[0]] = req.response;
+                nLeft = nLeft - 1;
+                if (nLeft == 0) {
+                  director.sendPayload(payload);
+                } else {
+                  bkey = bkeys[nLeft - 1];
+                  req.open("GET", bkey[1], true);
+                  req.responseType = "arraybuffer";
+                  req.onload = onLoad;
+                  req.send();
+                  exaine = payload;
+                }
+            }
+            req.onload = onLoad;
+            req.send();
+        }
+        loadBinaryPayload.call(this, payload1);
+    },
+
     enableDebug: function() {
         if(this.instanceView) {return;}
         this.instanceView = Ext.widget('widgetinstancesgrid');


diff -r c38c0acfcdc569644db232bbd23ecbe73418d4e0 -r 3bad7bdebdb1fa06754f27697ac31b2b79880c6d yt/gui/reason/html/app/controller/widgets/Scene.js
--- a/yt/gui/reason/html/app/controller/widgets/Scene.js
+++ b/yt/gui/reason/html/app/controller/widgets/Scene.js
@@ -28,12 +28,16 @@
 Ext.define("Reason.controller.widgets.Scene", {
     extend: 'Reason.controller.widgets.BaseWidget',
     requires: ['Reason.view.widgets.Scene',
+               'Reason.view.widgets.IsocontourCreator',
                'Reason.store.widgets.CameraKeyFrames',
+               'Reason.store.widgets.CameraPathElements',
                'Reason.store.widgets.SceneWidgets',
                'Ext.ux.CheckColumn'],
     templates: {
         createScene: 'widget_store.create_scene({varname})',
         deliverGrids: 'widget_store["{widget.varname}"].deliver_gridlines()',
+        createIsocontour: 'widget_store["{varname}"].deliver_isocontour(' +
+                          '"{field}", {value}, {relValue:capitalize})',
     },
 
     /* These call functions on the controller object */
@@ -43,6 +47,8 @@
         ["#renderPath", "click", "renderPath"],
         ["#keyframeview", "select", "shiftToKeyframe"],
         ["#widgetEnabled", "checkchange", "toggleWidgetEnabled"],
+        ["#addIsocontour", "click", "createIsocontour"],
+        ["#cameraPathSlider", "change", "updateCameraPosition"],
     ],
 
     /* These call templates */
@@ -54,17 +60,24 @@
         { ref:'scenePanel', selector: '#scenepanel' },
         { ref:'keyFrameView', selector: '#keyframeview' },
         { ref:'widgetPanel', selector: '#widgetlist'},
+        { ref:'cameraPathSlider', selector: '#cameraPathSlider'},
     ],
 
     /* key: , shift: and tpl: */
     keyTriggers: [
     ],
 
-
     applyPayload: function(payload) {
         if (payload['ptype'] == 'grid_lines') {
-            this.addGridLines(payload['corners'], payload['levels'],
-                              payload['max_level']);
+            payload['corners'] = new Float64Array(payload['corners']);
+            payload['levels'] = new Int32Array(payload['levels']);
+            this.addGridLines(payload['corners'], payload['levels'], payload['max_level']);
+        } else if (payload['ptype'] == 'isocontour') {
+            payload['vert'] = new Float64Array(payload['vert']);
+            payload['normals'] = new Float64Array(payload['normals']);
+            this.addIsocontour(payload['vert'], payload['normals']);
+        } else if (payload['ptype'] == 'camerapath') {
+            this.updateCameraPathElements(payload['data']);
         } else {
             console.log("Unknown payload type received for 3D scene: " +
                         payload['ptype']);
@@ -81,8 +94,11 @@
         this.applyExecuteHandlers(this.dataView);
         this.keyFrames = Ext.create("Reason.store.widgets.CameraKeyFrames");
         this.getKeyFrameView().bindStore(this.keyFrames);
+        this.pathElements = Ext.create("Reason.store.widgets.CameraPathElements");
         this.widgets = Ext.create("Reason.store.widgets.SceneWidgets");
         this.getWidgetPanel().bindStore(this.widgets);
+        this.fieldStore = Ext.create("Reason.store.Fields")
+        this.fieldStore.loadData(wd['fields']);
         return this.dataView;
     },
 
@@ -114,9 +130,10 @@
     },
 
     addGridLines: function(corners, levels, maxLevel) {
-        var i, g, n, p;
+        var i, g, n, p, offset, ind;
         var order1 = [0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3];
         var order2 = [1, 2, 3, 0, 5, 6, 7, 4, 4, 5, 6, 7];
+        var nv = levels.length;
         gw = [];
         for (i = 0; i < maxLevel + 1; i = i + 1) {
             var grids = new X.mesh();
@@ -129,18 +146,20 @@
             });
             grids.ga = "LINES";
         }
+        examine = {n: n, p: p, corners: corners};
+        var i0, i1, i2;
         Ext.each(levels, function(level, index, allLevels) {
             p = gw[level].points;
             n = gw[level].normals;
             for (i = 0; i < 12; i = i + 1) {
                 n.add(1.0, 0.0, 0.0);
                 n.add(1.0, 0.0, 0.0);
-                p.add(corners[order1[i]][0][index],
-                      corners[order1[i]][1][index],
-                      corners[order1[i]][2][index]);
-                p.add(corners[order2[i]][0][index],
-                      corners[order2[i]][1][index],
-                      corners[order2[i]][2][index]);
+                p.add(corners[(((order1[i] * 3 + 0)*nv)+index)],
+                      corners[(((order1[i] * 3 + 1)*nv)+index)],
+                      corners[(((order1[i] * 3 + 2)*nv)+index)]);
+                p.add(corners[(((order2[i] * 3 + 0)*nv)+index)],
+                      corners[(((order2[i] * 3 + 1)*nv)+index)],
+                      corners[(((order2[i] * 3 + 2)*nv)+index)]);
             }
         });
         for (i = 0; i < maxLevel + 1; i = i + 1) {
@@ -149,7 +168,61 @@
         this.renderer.render();
     },
 
+    createIsocontour: function() {
+        var win; 
+        var controller = this;
+        /* field , value */
+        function callExtract(b, e) {
+            var conf = {
+                varname: controller.dataView.varname,
+                field: win.query("#field")[0].getValue(),
+                value: win.query("#value")[0].getValue(),
+                relValue: "" + win.query("#relValue")[0].getValue(),
+            };
+            cmd = controller.templateManager.applyObject(
+                    conf, "createIsocontour");
+            reason.server.execute(cmd);
+            win.destroy();
+        }
+        win = Ext.widget("isocontourcreator");
+        win.query("#field")[0].bindStore(this.fieldStore);
+        win.query("#extract")[0].on('click', callExtract);
+        win.query("#cancel")[0].on('click', function(){win.destroy();});
+        win.show();
+    },
+
+    addIsocontour: function(vertices, normals) {
+        console.log("Adding isocontours ...");
+        var i, g, n, p;
+        var nv = vertices.length/3;
+        var last = 0;
+        var surf = new X.mesh();
+        this.widgets.add({
+          name: "Isocontour",
+          type: 'isocontour',
+          widget: surf,
+          enabled: true,
+        });
+        surf.ga = "TRIANGLES";
+        p = surf.points;
+        n = surf.normals;
+
+        for (index = 0; index < nv; index = index + 1) {
+            p.add(vertices[index * 3 + 0],
+                  vertices[index * 3 + 1],
+                  vertices[index * 3 + 2]);
+            n.add(normals[index * 3 + 0],
+                  normals[index * 3 + 1],
+                  normals[index * 3 + 2]);
+        }
+        surf.color = [1.0, 0.0, 0.0];
+        this.renderer.add(surf);
+        this.renderer.render();
+    },
+
     addKeyframe: function() {
+        this.getCameraPathSlider().setValue(0);
+        this.getCameraPathSlider().disable();
         var v = this.renderer.camera.view;
         var va = v.toArray();
         this.keyFrames.add({
@@ -174,13 +247,12 @@
     },
 
     renderPath: function() {
-        
         var t = new Ext.XTemplate("[[{0}, {1}, {2}, {3}], ",
                                   " [{4}, {5}, {6}, {7}], ",
                                   " [{8}, {9}, {10}, {11}], ",
                                   " [{12}, {13}, {14}, {15}]],\n");
         var cmdt = new Ext.XTemplate("widget_store['{0}'].render_path(\n",
-                                     "[{1}]\n,[{2}], 100)");
+                                     "[{1}]\n,[{2}], 101)");
         var path = "";
         var times = "";
         Ext.each(this.keyFrames.data.items, function(rec, ind, all) {
@@ -188,6 +260,29 @@
             path = path + t.apply(rec.data.view.flatten());
         });
         var cmd = cmdt.apply([this.dataView.varname, path, times]);
+        reason.server.execute(cmd);
+    },
+
+    updateCameraPathElements: function(elements) {
+        var cpe = this.pathElements;
+        var i;
+        cpe.removeAll();
+        for (i = 0; i < elements[0].length; i = i + 1) {
+            cpe.add({position: elements[0][i],
+                     focus: elements[1][i],
+                     up: elements[2][i]});
+        }
+        v = this.getCameraPathSlider().enable();
+    },
+
+    updateCameraPosition: function(b, e) {
+        v = this.getCameraPathSlider().getValue();
+        console.log(v);
+        rec = this.pathElements.data.items[v].data;
+        this.renderer.camera.position = rec.position;
+        this.renderer.camera.focus = rec.focus;
+        this.renderer.camera.up = rec.up;
+        this.renderer.render();
     },
 
 });


diff -r c38c0acfcdc569644db232bbd23ecbe73418d4e0 -r 3bad7bdebdb1fa06754f27697ac31b2b79880c6d yt/gui/reason/html/app/store/widgets/CameraPathElements.js
--- /dev/null
+++ b/yt/gui/reason/html/app/store/widgets/CameraPathElements.js
@@ -0,0 +1,36 @@
+/**********************************************************************
+Camera Path Element store for Reason
+
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2012 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define('Reason.store.widgets.CameraPathElements', {
+    extend: 'Ext.data.Store',
+    id: 'camerapathelements',
+    fields: [
+       {name: 'position'},
+       {name: 'focus'},
+       {name: 'up'},
+    ],
+    data: [],
+});
+


diff -r c38c0acfcdc569644db232bbd23ecbe73418d4e0 -r 3bad7bdebdb1fa06754f27697ac31b2b79880c6d yt/gui/reason/html/app/view/widgets/IsocontourCreator.js
--- /dev/null
+++ b/yt/gui/reason/html/app/view/widgets/IsocontourCreator.js
@@ -0,0 +1,78 @@
+/**********************************************************************
+The Isocontour Creator
+
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2012 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+Ext.define("Reason.view.widgets.IsocontourCreator", {
+    extend: 'Ext.window.Window',
+    alias: 'widget.isocontourcreator',
+    width: 370,
+    height: 200,
+    modal: true,
+    resizable: false,
+    draggable: false,
+    border: false,
+    layout: 'fit',
+    title: "Create Phase Plot",
+
+    items: [{ xtype: 'form', // FormPanel
+              labelWidth:80,
+              frame:true,
+              items: [ {
+                xtype:'combo',
+                fieldLabel: 'Field',
+                id: 'field',
+                width: 290,
+                queryMode: 'local',
+                editable: false,
+                triggerAction: 'all',
+                value: 'Density'
+              },{
+                xtype:'checkboxfield',
+                fieldLabel: 'Relative Value?',
+                itemId: 'relValue',
+                value: true,
+                checked: true,
+                width: 290,
+                allowBlank:false,
+              },{
+                xtype:'textfield',
+                fieldLabel: 'Value',
+                itemId: 'value',
+                value: '0.5',
+                width: 290,
+                allowBlank:false,
+              }
+            ],
+            buttons: [
+                {
+                    text: 'Extract',
+                    itemId: 'extract',
+                },{
+                    text: 'Cancel',
+                    itemId: 'cancel',
+                }
+            ]
+        }],
+});
+


diff -r c38c0acfcdc569644db232bbd23ecbe73418d4e0 -r 3bad7bdebdb1fa06754f27697ac31b2b79880c6d yt/gui/reason/html/app/view/widgets/Scene.js
--- a/yt/gui/reason/html/app/view/widgets/Scene.js
+++ b/yt/gui/reason/html/app/view/widgets/Scene.js
@@ -48,6 +48,7 @@
         }, {
             xtype: 'multislider',
             itemId: 'cameraPathSlider',
+            disabled: true,
             minValue: 0,
             maxValue: 100,
             increment: 1,
@@ -183,6 +184,11 @@
                   layout: 'absolute',
                   flex: 1,
                   items : [
+                    {
+                      xtype: 'button',
+                      text: 'Add Isocontour',
+                      itemId: 'addIsocontour'
+                    },
                   ]
                 },
                 ] } /* tabpanel items and entry */


diff -r c38c0acfcdc569644db232bbd23ecbe73418d4e0 -r 3bad7bdebdb1fa06754f27697ac31b2b79880c6d yt/gui/reason/widget_builders.py
--- a/yt/gui/reason/widget_builders.py
+++ b/yt/gui/reason/widget_builders.py
@@ -78,63 +78,20 @@
 def get_corners(pf, max_level=None):
     DL = pf.domain_left_edge[None,:,None]
     DW = pf.domain_width[None,:,None]/100.0
-    corners = ((pf.h.grid_corners-DL)/DW).tolist()
-    levels = pf.h.grid_levels.tolist()
+    corners = ((pf.h.grid_corners-DL)/DW)
+    levels = pf.h.grid_levels
     return corners, levels
 
-def get_grid_vertices(pf, max_level=None):
-    if max_level is None: max_level = pf.h.max_level
-    fns = []
-    for lvl in range(max_level):
-        fn = "%s_lvl_%02i_grids.vtk"%(pf, lvl)
-        f = open(fn, "w")
-
-        f.write("""# vtk DataFile Version 3.0
-        vtk output
-        ASCII
-        DATASET POLYDATA
-        POINTS %s float
-        """ % (pf.h.num_grids * 8))
-
-        for gi in xrange(pf.h.num_grids):
-            if pf.h.grid_levels[gi][0] != lvl: continue
-            gc = pf.h.grid_corners[:, :, gi] * 100.0
-            for i in range(8):
-                f.write("%0.9f %0.9f %0.9f\n" % (gc[i, 0], gc[i, 1], gc[i, 2]))
-
-        f.write("LINES %s %s\n" % (pf.h.num_grids * 12, 3 * pf.h.num_grids * 12))
-
-        order1 = (0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3)
-        order2 = (1, 2, 3, 0, 5, 6, 7, 4, 4, 5, 6, 7)
-
-        for gi in xrange(pf.h.num_grids):
-            if pf.h.grid_levels[gi][0] != lvl: continue
-            offset = 8 * gi
-            for p1, p2 in zip(order1, order2):
-                f.write("2 %s %s\n" % (p1 + offset, p2 + offset))
-        f.close()
-        fns.append(fn)
-    return fn
-
-def get_isocontour(pf, field, value=None):
+def get_isocontour(pf, field, value=None, rel_val = False):
 
     dd = pf.h.all_data()
-    if value is None:
+    if value is None or rel_val:
+        if value is None: value = 0.5
         mi, ma = na.log10(dd.quantities["Extrema"]("Density")[0])
-        value = 10.**((mi + ma)/2.)
+        value = 10.0**(value*(ma - mi) + mi)
     vert = dd.extract_isocontours("Density", value)
     na.multiply(vert, 100, vert)
-
-    fn = "%s_surface.vtk" % pf
-    f = open(fn, "w")
-    f.write("vtk output\nASCII\nDATASET POLYDATA\nPOINTS %s float\n" % (vert.shape[0]))
-    for v in vert:
-        f.write("%0.14f %0.14f %0.14f\n" % (v[0], v[1], v[2]))
-    f.write("VERTICES %s %s\n" % (vert.shape[0]/3, vert.shape[0] + vert.shape[0]/3))
-    for i in range(vert.shape[0]/3):
-        f.write("3 %i %i %i\n" % (i*3, i*3+1, i*3+2))
-    f.close()
-    return fn
+    return vert
 
 def get_streamlines(pf):
     from yt.visualization.api import Streamlines


diff -r c38c0acfcdc569644db232bbd23ecbe73418d4e0 -r 3bad7bdebdb1fa06754f27697ac31b2b79880c6d yt/gui/reason/widget_store.py
--- a/yt/gui/reason/widget_store.py
+++ b/yt/gui/reason/widget_store.py
@@ -26,8 +26,9 @@
 from yt.mods import *
 import weakref
 from .bottle_mods import PayloadHandler, lockit
-from .widget_builders import RenderingScene, get_corners
+from .widget_builders import RenderingScene, get_corners, get_isocontour
 from yt.visualization.plot_window import PWViewerExtJS
+from yt.visualization.volume_rendering.create_spline import create_spline
 import uuid
 
 _phase_plot_mds = """<pre>
@@ -163,7 +164,11 @@
     def create_scene(self, pf):
         '''Creates 3D XTK-based scene'''
         widget = SceneWidget(pf)
-        widget_data = {'title':'Scene for %s' % pf}
+        field_list = list(set(pf.h.field_list
+                            + pf.h.derived_field_list))
+        field_list.sort()
+        widget_data = {'title':'Scene for %s' % pf,
+                       'fields': field_list}
         self._add_widget(widget, widget_data)
 
 
@@ -229,15 +234,64 @@
                                  'image':self._rendering_scene.snapshot()})
         return
 
+    def deliver_isocontour(self, field, value, rel_val = False):
+        ph = PayloadHandler()
+        vert = get_isocontour(self.pf, field, value, rel_val)
+        normals = na.empty(vert.shape)
+        for i in xrange(vert.shape[0]/3):
+            n = na.cross(vert[i*3,:], vert[i*3+1,:])
+            normals[i*3:i*3+3,:] = n[None,:]
+        ph.widget_payload(self, {'ptype':'isocontour',
+                                 'binary': ['vert', 'normals'],
+                                 'vert':vert,
+                                 'normals':normals})
+
     def deliver_gridlines(self):
         ph = PayloadHandler()
         corners, levels = get_corners(self.pf)
         ph.widget_payload(self, {'ptype':'grid_lines',
+                                 'binary': ['corners', 'levels'],
                                  'corners': corners,
                                  'levels': levels,
                                  'max_level': int(self.pf.h.max_level)})
         return
 
+    def render_path(self, views, times, N):
+        # Assume that path comes in as a list of matrice
+        # Assume original vector is (0., 0., 1.), up is (0., 1., 0.)
+        # for matrix in matrices:
+
+        views = [na.array(view) for view in views]
+        
+        times = na.linspace(0.0,1.0,len(times))
+        norm = na.array([0.,0.,1.,1.])
+        up = na.array([0.,1.,0.,1.])
+        
+        centers = na.array([na.dot(na.eye(4)*R[3,2],na.dot(R, norm)) for R in views])
+        r = views[0]
+        print r 
+        ups = na.array([na.dot(R,up) for R in views])
+        print 'centers'
+        for center in centers: print center
+        print 'ups'
+        for up in ups: print up
+
+        pos = na.empty((N,3), dtype="float64")
+        uv = na.empty((N,3), dtype="float64")
+        f = na.zeros((N,3), dtype="float64")
+        for i in range(3):
+            pos[:,i] = create_spline(times, centers[:,i], na.linspace(0.0,1.0,N))
+            uv[:,i] = create_spline(times, ups[:,i], na.linspace(0.0,1.0,N))
+    
+        path = [pos.tolist(), f.tolist(), uv.tolist()]
+    
+        ph = PayloadHandler()
+        ph.widget_payload(self, {'ptype':'camerapath',
+                                 'data':path,})
+
+        return
+
+
     def deliver_streamlines(self):
         pf = PayloadHandler()
         pass


diff -r c38c0acfcdc569644db232bbd23ecbe73418d4e0 -r 3bad7bdebdb1fa06754f27697ac31b2b79880c6d yt/visualization/volume_rendering/camera.py
--- a/yt/visualization/volume_rendering/camera.py
+++ b/yt/visualization/volume_rendering/camera.py
@@ -229,6 +229,9 @@
         self.back_center =  center - 0.5*width[2]*unit_vectors[2]
         self.front_center = center + 0.5*width[2]*unit_vectors[2]         
 
+    def update_view_from_matrix(self, mat):
+        pass
+
     def look_at(self, new_center, north_vector = None):
         r"""Change the view direction based on a new focal point.
 



https://bitbucket.org/yt_analysis/yt/changeset/93b21ffa90db/
changeset:   93b21ffa90db
branch:      yt
user:        MatthewTurk
date:        2012-06-24 04:24:34
summary:     load_script and deliver_image work again.
affected #:  5 files

diff -r 3bad7bdebdb1fa06754f27697ac31b2b79880c6d -r 93b21ffa90db0f173b80aae2533f1c11e0901498 yt/gui/reason/extdirect_repl.py
--- a/yt/gui/reason/extdirect_repl.py
+++ b/yt/gui/reason/extdirect_repl.py
@@ -121,6 +121,7 @@
                 {'type': 'cell',
                  'output': result,
                  'input': highlighter(code),
+                 'image_data': '',
                  'raw_input': code},
                 )
         objs = get_list_of_datasets()
@@ -168,6 +169,7 @@
 
 
 def reason_pylab():
+    from .utils import deliver_image
     def _canvas_deliver(canvas):
         tf = tempfile.TemporaryFile()
         canvas.print_png(tf)


diff -r 3bad7bdebdb1fa06754f27697ac31b2b79880c6d -r 93b21ffa90db0f173b80aae2533f1c11e0901498 yt/gui/reason/html/app/controller/Notebook.js
--- a/yt/gui/reason/html/app/controller/Notebook.js
+++ b/yt/gui/reason/html/app/controller/Notebook.js
@@ -48,6 +48,7 @@
     init: function() {
         this.application.addListener({
             payloadcell: {fn: this.addCell, scope: this},
+            payloadscript: {fn: this.loadScript, scope: this},
             executecell: {fn: this.executeCell, scope: this},
             wipeinput:   {fn: this.wipeInputLine, scope: this},
             blockinput:  {fn: this.blockInput, scope: this},
@@ -78,10 +79,18 @@
             input: cell['input'],
             output: cell['output'],
             raw_input: cell['raw_input'],
+            image_data: cell['image_data'],
             executiontime: cell['executiontime'],
         });
         this.application.fireEvent("scrolltobottom");
     },
+
+    loadScript: function(payload) {
+        console.log("Loading script ...");
+        this.getInputLine().setValue(payload['value']);
+        this.getInputLine()._lock = true;
+    },
+
     executeCell: function(line) {
         this.application.fireEvent("blockinput");
         console.log("Asked to execute " + line);
@@ -95,7 +104,11 @@
     },
     
     wipeInputLine: function() {
-        this.getInputLine().setValue("");
+        if(this.getInputLine()._lock == true) {
+            this.getInputLine()._lock = false;
+        } else {
+            this.getInputLine().setValue("");
+        }
     },
 
     blockInput: function() {


diff -r 3bad7bdebdb1fa06754f27697ac31b2b79880c6d -r 93b21ffa90db0f173b80aae2533f1c11e0901498 yt/gui/reason/html/app/store/CellValues.js
--- a/yt/gui/reason/html/app/store/CellValues.js
+++ b/yt/gui/reason/html/app/store/CellValues.js
@@ -32,7 +32,9 @@
 Ext.define('Reason.store.CellValues', {
     extend: 'Ext.data.Store',
     id: 'cellvalues',
-    fields: ['input', 'output', 'raw_input', 'executiontime'],
+    fields: ['input', 'output', 'raw_input', 'executiontime', 
+        { name: 'image_data', type: 'string', defaultValue: '' }
+    ],
     data: [],
 });
 


diff -r 3bad7bdebdb1fa06754f27697ac31b2b79880c6d -r 93b21ffa90db0f173b80aae2533f1c11e0901498 yt/gui/reason/html/app/view/CellView.js
--- a/yt/gui/reason/html/app/view/CellView.js
+++ b/yt/gui/reason/html/app/view/CellView.js
@@ -38,6 +38,13 @@
     '<pre>{output}</pre><br/><br/>'
 );
 
+var imageDisplay = new Ext.XTemplate(
+    '<b>Image</b><br/><br/>',
+    '<hr>',
+    '<img src="data:image/png;base64,{image_data}">',
+    '<br/><br/>'
+);
+
 Ext.define('Reason.view.CellView', {
     extend: 'Ext.grid.Panel',
     alias: 'widget.notebookcells',
@@ -56,8 +63,15 @@
     features: [{
         ftype: 'rowbody',
         getAdditionalData: function(data, rowIndex, record, orig) {
+            var disp;
+            console.log(data);
+            if(data['image_data'] != '') {
+                disp = imageDisplay.apply(data);
+            } else {
+                disp = cellDisplay.apply(data);
+            }
             return {
-                rowBody: cellDisplay.apply(data),
+                rowBody: disp,
                 rowBodyCls: 'codeview',
                 rowBodyColspan: this.view.headerCt.getColumnCount(),
             };


diff -r 3bad7bdebdb1fa06754f27697ac31b2b79880c6d -r 93b21ffa90db0f173b80aae2533f1c11e0901498 yt/gui/reason/utils.py
--- a/yt/gui/reason/utils.py
+++ b/yt/gui/reason/utils.py
@@ -33,7 +33,7 @@
     contents = open(filename).read()
     payload_handler = PayloadHandler()
     payload_handler.add_payload(
-        {'type': 'cell_contents',
+        {'type': 'script',
          'value': contents}
     )
     return
@@ -49,7 +49,10 @@
     else:
         raise RuntimeError
     ph = PayloadHandler()
-    payload = {'type':'png_string',
+    payload = {'type':'cell',
+               'output': '',
+               'input': '',
+               'raw_input': '',
                'image_data':img_data}
     ph.add_payload(payload)
 



https://bitbucket.org/yt_analysis/yt/changeset/e85c61e5b169/
changeset:   e85c61e5b169
branch:      yt
user:        brittonsmith
date:        2012-06-24 04:47:01
summary:     Pyro server script now writes HMAC key to a file that
only the user has permissions to.
affected #:  1 file

diff -r 3bad7bdebdb1fa06754f27697ac31b2b79880c6d -r e85c61e5b169c838c5e60d0512be950042ee7a5b scripts/pyro_queue.py
--- a/scripts/pyro_queue.py
+++ b/scripts/pyro_queue.py
@@ -1,3 +1,4 @@
+import os
 import Pyro4
 import uuid
 
@@ -14,10 +15,16 @@
 if my_rank == 0:
     my_q = PyroQueueRoot(comm)
     Pyro4.config.HMAC_KEY = uuid.uuid4().hex
-    print "HMAC KEY", Pyro4.config.HMAC_KEY
+    key_file = 'reason.key'
+    fd = os.open(key_file, os.O_CREAT, 0600)
+    os.close(fd)
+    out_file = file(key_file, 'w')
+    out_file.write("HMAC KEY: %s\n" % Pyro4.config.HMAC_KEY)
+    out_file.close()
+    mylog.info('See %s for HMAC key.', key_file)
     Pyro4.Daemon.serveSimple(
         {my_q: "yt.executor"},
-        ns=False)
+        ns=False, verbose=True)
 else:
     my_q = PyroQueueNonRoot(comm)
     my_q.run()



https://bitbucket.org/yt_analysis/yt/changeset/75214b69375f/
changeset:   75214b69375f
branch:      yt
user:        brittonsmith
date:        2012-06-24 04:47:18
summary:     Merged.
affected #:  5 files

diff -r e85c61e5b169c838c5e60d0512be950042ee7a5b -r 75214b69375f3171d908a300bc769e569925bc9c yt/gui/reason/extdirect_repl.py
--- a/yt/gui/reason/extdirect_repl.py
+++ b/yt/gui/reason/extdirect_repl.py
@@ -121,6 +121,7 @@
                 {'type': 'cell',
                  'output': result,
                  'input': highlighter(code),
+                 'image_data': '',
                  'raw_input': code},
                 )
         objs = get_list_of_datasets()
@@ -168,6 +169,7 @@
 
 
 def reason_pylab():
+    from .utils import deliver_image
     def _canvas_deliver(canvas):
         tf = tempfile.TemporaryFile()
         canvas.print_png(tf)


diff -r e85c61e5b169c838c5e60d0512be950042ee7a5b -r 75214b69375f3171d908a300bc769e569925bc9c yt/gui/reason/html/app/controller/Notebook.js
--- a/yt/gui/reason/html/app/controller/Notebook.js
+++ b/yt/gui/reason/html/app/controller/Notebook.js
@@ -48,6 +48,7 @@
     init: function() {
         this.application.addListener({
             payloadcell: {fn: this.addCell, scope: this},
+            payloadscript: {fn: this.loadScript, scope: this},
             executecell: {fn: this.executeCell, scope: this},
             wipeinput:   {fn: this.wipeInputLine, scope: this},
             blockinput:  {fn: this.blockInput, scope: this},
@@ -78,10 +79,18 @@
             input: cell['input'],
             output: cell['output'],
             raw_input: cell['raw_input'],
+            image_data: cell['image_data'],
             executiontime: cell['executiontime'],
         });
         this.application.fireEvent("scrolltobottom");
     },
+
+    loadScript: function(payload) {
+        console.log("Loading script ...");
+        this.getInputLine().setValue(payload['value']);
+        this.getInputLine()._lock = true;
+    },
+
     executeCell: function(line) {
         this.application.fireEvent("blockinput");
         console.log("Asked to execute " + line);
@@ -95,7 +104,11 @@
     },
     
     wipeInputLine: function() {
-        this.getInputLine().setValue("");
+        if(this.getInputLine()._lock == true) {
+            this.getInputLine()._lock = false;
+        } else {
+            this.getInputLine().setValue("");
+        }
     },
 
     blockInput: function() {


diff -r e85c61e5b169c838c5e60d0512be950042ee7a5b -r 75214b69375f3171d908a300bc769e569925bc9c yt/gui/reason/html/app/store/CellValues.js
--- a/yt/gui/reason/html/app/store/CellValues.js
+++ b/yt/gui/reason/html/app/store/CellValues.js
@@ -32,7 +32,9 @@
 Ext.define('Reason.store.CellValues', {
     extend: 'Ext.data.Store',
     id: 'cellvalues',
-    fields: ['input', 'output', 'raw_input', 'executiontime'],
+    fields: ['input', 'output', 'raw_input', 'executiontime', 
+        { name: 'image_data', type: 'string', defaultValue: '' }
+    ],
     data: [],
 });
 


diff -r e85c61e5b169c838c5e60d0512be950042ee7a5b -r 75214b69375f3171d908a300bc769e569925bc9c yt/gui/reason/html/app/view/CellView.js
--- a/yt/gui/reason/html/app/view/CellView.js
+++ b/yt/gui/reason/html/app/view/CellView.js
@@ -38,6 +38,13 @@
     '<pre>{output}</pre><br/><br/>'
 );
 
+var imageDisplay = new Ext.XTemplate(
+    '<b>Image</b><br/><br/>',
+    '<hr>',
+    '<img src="data:image/png;base64,{image_data}">',
+    '<br/><br/>'
+);
+
 Ext.define('Reason.view.CellView', {
     extend: 'Ext.grid.Panel',
     alias: 'widget.notebookcells',
@@ -56,8 +63,15 @@
     features: [{
         ftype: 'rowbody',
         getAdditionalData: function(data, rowIndex, record, orig) {
+            var disp;
+            console.log(data);
+            if(data['image_data'] != '') {
+                disp = imageDisplay.apply(data);
+            } else {
+                disp = cellDisplay.apply(data);
+            }
             return {
-                rowBody: cellDisplay.apply(data),
+                rowBody: disp,
                 rowBodyCls: 'codeview',
                 rowBodyColspan: this.view.headerCt.getColumnCount(),
             };


diff -r e85c61e5b169c838c5e60d0512be950042ee7a5b -r 75214b69375f3171d908a300bc769e569925bc9c yt/gui/reason/utils.py
--- a/yt/gui/reason/utils.py
+++ b/yt/gui/reason/utils.py
@@ -33,7 +33,7 @@
     contents = open(filename).read()
     payload_handler = PayloadHandler()
     payload_handler.add_payload(
-        {'type': 'cell_contents',
+        {'type': 'script',
          'value': contents}
     )
     return
@@ -49,7 +49,10 @@
     else:
         raise RuntimeError
     ph = PayloadHandler()
-    payload = {'type':'png_string',
+    payload = {'type':'cell',
+               'output': '',
+               'input': '',
+               'raw_input': '',
                'image_data':img_data}
     ph.add_payload(payload)
 



https://bitbucket.org/yt_analysis/yt/changeset/632bff56e1e8/
changeset:   632bff56e1e8
branch:      yt
user:        MatthewTurk
date:        2012-06-24 04:48:48
summary:     Switching:

  * Deploy only a zip file of the ExtJS + Leaflet + XTK javascript
  * Switch get_enzotools to get_ytproject
  * Output how to download the zip if you don't have it
affected #:  4 files

diff -r 75214b69375f3171d908a300bc769e569925bc9c -r 632bff56e1e8431e91eb37188c2d8c92ad729d55 doc/install_script.sh
--- a/doc/install_script.sh
+++ b/doc/install_script.sh
@@ -332,7 +332,7 @@
     sleep 60
 fi
 
-function get_enzotools
+function get_ytproject
 {
     echo "Downloading $1 from yt-project.org"
     [ -e $1 ] && return
@@ -358,7 +358,7 @@
 echo '44eea803870a66ff0bab08d13a8b3388b5578ebc1c807d1d9dca0a93e6371e91b15d02917a00b3b20dc67abb5a21dabaf9b6e9257a561f85eeff2147ac73b478  PyX-0.11.1.tar.gz' > PyX-0.11.1.tar.gz.sha512
 echo '1a754d560bfa433f0960ab3b5a62edb5f291be98ec48cf4e5941fa5b84139e200b87a52efbbd6fa4a76d6feeff12439eed3e7a84db4421940d1bbb576f7a684e  Python-2.7.2.tgz' > Python-2.7.2.tgz.sha512
 echo 'c017d3d59dd324ac91af0edc178c76b60a5f90fbb775cf843e39062f95bd846238f2c53705f8890ed3f34bc0e6e75671a73d13875eb0287d6201cb45f0a2d338  bzip2-1.0.5.tar.gz' > bzip2-1.0.5.tar.gz.sha512
-echo '445de41f63a03bf1c098e36b5658590d8837a80ecd3ce8ff6544d30653cc64ce2521e6354016ca3b56a35a8416c33567506db8acec29ea3d9d97ae5f2e7eca02  ext-4.1.0-gpl.zip' > ext-4.1.0-gpl.zip.sha512
+echo 'a296dfcaef7e853e58eed4e24b37c4fa29cfc6ac688def048480f4bb384b9e37ca447faf96eec7b378fd764ba291713f03ac464581d62275e28eb2ec99110ab6  reason-js-20120623.zip' > reason-js-20120623.zip.sha512
 echo 'b519218f93946400326e9b656669269ecb3e5232b944e18fbc3eadc4fe2b56244d68aae56d6f69042b4c87c58c881ee2aaa279561ea0f0f48d5842155f4de9de  freetype-2.4.4.tar.gz' > freetype-2.4.4.tar.gz.sha512
 echo '1531789e0a77d4829796d18552a4de7aecae7e8b63763a7951a8091921995800740fe03e72a7dbd496a5590828131c5f046ddead695e5cba79343b8c205148d1  h5py-2.0.1.tar.gz' > h5py-2.0.1.tar.gz.sha512
 echo '9644896e4a84665ad22f87eb885cbd4a0c60a5c30085d5dd5dba5f3c148dbee626f0cb01e59a7995a84245448a3f1e9ba98687d3f10250e2ee763074ed8ddc0e  hdf5-1.8.7.tar.gz' > hdf5-1.8.7.tar.gz.sha512
@@ -374,24 +374,24 @@
 echo '57fa5e57dfb98154a42d2d477f29401c2260ae7ad3a8128a4098b42ee3b35c54367b1a3254bc76b9b3b14b4aab7c3e1135858f68abc5636daedf2f01f9b8a3cf  tornado-2.2.tar.gz' > tornado-2.2.tar.gz.sha512
 
 # Individual processes
-[ -z "$HDF5_DIR" ] && get_enzotools hdf5-1.8.7.tar.gz
-[ $INST_ZLIB -eq 1 ] && get_enzotools zlib-1.2.3.tar.bz2 
-[ $INST_BZLIB -eq 1 ] && get_enzotools bzip2-1.0.5.tar.gz
-[ $INST_PNG -eq 1 ] && get_enzotools libpng-1.2.43.tar.gz
-[ $INST_FTYPE -eq 1 ] && get_enzotools freetype-2.4.4.tar.gz
-[ $INST_SQLITE3 -eq 1 ] && get_enzotools sqlite-autoconf-3070500.tar.gz
-[ $INST_PYX -eq 1 ] && get_enzotools PyX-0.11.1.tar.gz
-[ $INST_0MQ -eq 1 ] && get_enzotools zeromq-2.2.0.tar.gz
-[ $INST_0MQ -eq 1 ] && get_enzotools pyzmq-2.1.11.tar.gz
-[ $INST_0MQ -eq 1 ] && get_enzotools tornado-2.2.tar.gz
-get_enzotools Python-2.7.2.tgz
-get_enzotools numpy-1.6.1.tar.gz
-get_enzotools matplotlib-1.1.0.tar.gz
-get_enzotools mercurial-2.2.2.tar.gz
-get_enzotools ipython-0.12.tar.gz
-get_enzotools h5py-2.0.1.tar.gz
-get_enzotools Cython-0.16.tar.gz
-get_enzotools ext-4.1.0-gpl.zip
+[ -z "$HDF5_DIR" ] && get_ytproject hdf5-1.8.7.tar.gz
+[ $INST_ZLIB -eq 1 ] && get_ytproject zlib-1.2.3.tar.bz2 
+[ $INST_BZLIB -eq 1 ] && get_ytproject bzip2-1.0.5.tar.gz
+[ $INST_PNG -eq 1 ] && get_ytproject libpng-1.2.43.tar.gz
+[ $INST_FTYPE -eq 1 ] && get_ytproject freetype-2.4.4.tar.gz
+[ $INST_SQLITE3 -eq 1 ] && get_ytproject sqlite-autoconf-3070500.tar.gz
+[ $INST_PYX -eq 1 ] && get_ytproject PyX-0.11.1.tar.gz
+[ $INST_0MQ -eq 1 ] && get_ytproject zeromq-2.2.0.tar.gz
+[ $INST_0MQ -eq 1 ] && get_ytproject pyzmq-2.1.11.tar.gz
+[ $INST_0MQ -eq 1 ] && get_ytproject tornado-2.2.tar.gz
+get_ytproject Python-2.7.2.tgz
+get_ytproject numpy-1.6.1.tar.gz
+get_ytproject matplotlib-1.1.0.tar.gz
+get_ytproject mercurial-2.2.2.tar.gz
+get_ytproject ipython-0.12.tar.gz
+get_ytproject h5py-2.0.1.tar.gz
+get_ytproject Cython-0.16.tar.gz
+get_ytproject reason-js-20120623.zip
 
 if [ $INST_BZLIB -eq 1 ]
 then


diff -r 75214b69375f3171d908a300bc769e569925bc9c -r 632bff56e1e8431e91eb37188c2d8c92ad729d55 yt/gui/reason/extdirect_repl.py
--- a/yt/gui/reason/extdirect_repl.py
+++ b/yt/gui/reason/extdirect_repl.py
@@ -223,11 +223,10 @@
     debug = False
     _heartbeat_timer = None
 
-    def __init__(self, base_extjs_path, locals=None,
+    def __init__(self, reasonjs_path, locals=None,
                  use_pyro=False):
         # First we do the standard initialization
-        self.extjs_file = zipfile.ZipFile(os.path.join(
-            base_extjs_path, "ext-4.1.0-gpl.zip"), 'r')
+        self.reasonjs_file = zipfile.ZipFile(reasonjs_path, 'r')
         ProgrammaticREPL.__init__(self, locals)
         # Now, since we want to only preroute functions we know about, and
         # since they have different arguments, and most of all because we only
@@ -239,7 +238,7 @@
                               _myapi = ("/ext-repl-api.js", "GET"),
                               _session_py = ("/session.py", "GET"),
                               _highlighter_css = ("/highlighter.css", "GET"),
-                              _extjs = ("/resources/extjs-4.1.0/:path#.+#", "GET"),
+                              _reasonjs = ("/reason-js/:path#.+#", "GET"),
                               _app = ("/reason/:path#.+#", "GET"),
                               )
         for v, args in preroute_table.items():
@@ -331,10 +330,10 @@
         root = os.path.join(local_dir, "html")
         return static_file("help.html", root)
 
-    def _extjs(self, path):
-        pp = os.path.join("extjs-4.1.0", path)
+    def _reasonjs(self, path):
+        pp = os.path.join("reason-js", path)
         try:
-            f = self.extjs_file.open(pp)
+            f = self.reasonjs_file.open(pp)
         except KeyError:
             response.status = 404
             return


diff -r 75214b69375f3171d908a300bc769e569925bc9c -r 632bff56e1e8431e91eb37188c2d8c92ad729d55 yt/gui/reason/html/index.html
--- a/yt/gui/reason/html/index.html
+++ b/yt/gui/reason/html/index.html
@@ -8,12 +8,12 @@
     <link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Inconsolata"><!-- LIBS -->
-    <link rel="stylesheet" type="text/css" href="resources/extjs-4.1.0/resources/css/ext-all-gray.css">
+    <link rel="stylesheet" type="text/css" href="reason-js/resources/css/ext-all-gray.css"><link rel="stylesheet" type="text/css" href="reason/resources/css/style.css"><link rel="stylesheet" type="text/css" href="reason/resources/css/CheckHeader.css"><link rel="stylesheet" type="text/css" href="highlighter.css">
 
-    <script type="text/javascript" src="resources/extjs-4.1.0/ext-all-debug.js"></script>
+    <script type="text/javascript" src="reason-js/ext-all.js"></script><script type="text/javascript" src="reason/app.js"></script><script type="text/javascript" src="ext-repl-api.js"></script>
 
@@ -21,11 +21,11 @@
     <script type="text/javascript" src="reason/resources/ux/CheckColumn.js"></script><!-- LEAFLET STUFF -->
-    <script type="text/javascript" src="reason/resources/leaflet/leaflet.js"></script>
-    <link rel="stylesheet" href="reason/resources/leaflet/leaflet.css" />
+    <script type="text/javascript" src="reason-js/leaflet/leaflet.js"></script>
+    <link rel="stylesheet" href="reason-js/leaflet/leaflet.css" /><!-- XTK STUFF -->
-    <script type="text/javascript" src="reason/xtk_edge.js"></script>
+    <script type="text/javascript" src="reason-js/xtk_edge.js"></script></head><body>


diff -r 75214b69375f3171d908a300bc769e569925bc9c -r 632bff56e1e8431e91eb37188c2d8c92ad729d55 yt/utilities/command_line.py
--- a/yt/utilities/command_line.py
+++ b/yt/utilities/command_line.py
@@ -1310,20 +1310,26 @@
             except ValueError:
                 print "Please try a number next time."
                 return 1
-        base_extjs_path = os.path.join(os.environ["YT_DEST"], "src")
-        if not os.path.isfile(os.path.join(base_extjs_path, "ext-resources", "ext-all.js")):
+        fn = "reason-js-20120623.zip"
+        reasonjs_path = os.path.join(os.environ["YT_DEST"], "src", fn)
+        if not os.path.isfile(reasonjs_path):
             print
-            print "*** You are missing the ExtJS support files. You  ***"
+            print "*** You are missing the Reason support files. You ***"
             print "*** You can get these by either rerunning the     ***"
             print "*** install script installing, or downloading     ***"
             print "*** them manually.                                ***"
+            print "***                                               ***"
+            print "*** FOR INSTANCE:                                 ***"
+            print
+            print "cd %s" % os.path.join(os.environ["YT_DEST"], "src")
+            print "wget http://yt-project.org/dependencies/reason-js-20120623.zip"
             print
             sys.exit(1)
         from yt.config import ytcfg;ytcfg["yt","__withinreason"]="True"
         import yt.utilities.bottle as bottle
         from yt.gui.reason.extdirect_repl import ExtDirectREPL
         from yt.gui.reason.bottle_mods import uuid_serve_functions, PayloadHandler
-        hr = ExtDirectREPL(base_extjs_path, use_pyro=args.use_pyro)
+        hr = ExtDirectREPL(reasonjs_path, use_pyro=args.use_pyro)
         hr.debug = PayloadHandler.debug = args.debug
         command_line = ["pfs = []"]
         if args.find:



https://bitbucket.org/yt_analysis/yt/changeset/054f19f0fe56/
changeset:   054f19f0fe56
branch:      yt
user:        MatthewTurk
date:        2012-06-24 04:56:33
summary:     Removing leaflet, which we now ship separately.  Should never have been
versioned.
affected #:  8 files

diff -r 632bff56e1e8431e91eb37188c2d8c92ad729d55 -r 054f19f0fe563c6c99b345b1c1f9e271d085f7b0 yt/gui/reason/html/resources/leaflet/images/marker-shadow.png
Binary file yt/gui/reason/html/resources/leaflet/images/marker-shadow.png has changed


diff -r 632bff56e1e8431e91eb37188c2d8c92ad729d55 -r 054f19f0fe563c6c99b345b1c1f9e271d085f7b0 yt/gui/reason/html/resources/leaflet/images/marker.png
Binary file yt/gui/reason/html/resources/leaflet/images/marker.png has changed


diff -r 632bff56e1e8431e91eb37188c2d8c92ad729d55 -r 054f19f0fe563c6c99b345b1c1f9e271d085f7b0 yt/gui/reason/html/resources/leaflet/images/popup-close.png
Binary file yt/gui/reason/html/resources/leaflet/images/popup-close.png has changed


diff -r 632bff56e1e8431e91eb37188c2d8c92ad729d55 -r 054f19f0fe563c6c99b345b1c1f9e271d085f7b0 yt/gui/reason/html/resources/leaflet/images/zoom-in.png
Binary file yt/gui/reason/html/resources/leaflet/images/zoom-in.png has changed


diff -r 632bff56e1e8431e91eb37188c2d8c92ad729d55 -r 054f19f0fe563c6c99b345b1c1f9e271d085f7b0 yt/gui/reason/html/resources/leaflet/images/zoom-out.png
Binary file yt/gui/reason/html/resources/leaflet/images/zoom-out.png has changed


diff -r 632bff56e1e8431e91eb37188c2d8c92ad729d55 -r 054f19f0fe563c6c99b345b1c1f9e271d085f7b0 yt/gui/reason/html/resources/leaflet/leaflet.css
--- a/yt/gui/reason/html/resources/leaflet/leaflet.css
+++ /dev/null
@@ -1,273 +0,0 @@
-/* required styles */
-
-.leaflet-map-pane,
-.leaflet-tile,
-.leaflet-marker-icon, 
-.leaflet-marker-shadow,
-.leaflet-tile-pane, 
-.leaflet-overlay-pane,
-.leaflet-shadow-pane,
-.leaflet-marker-pane,
-.leaflet-popup-pane,
-.leaflet-overlay-pane svg,
-.leaflet-zoom-box,
-.leaflet-image-layer { /* TODO optimize classes */ 
-	position: absolute;
-	}
-.leaflet-container {
-	overflow: hidden;
-	}
-.leaflet-tile-pane {
-	-webkit-transform: translate3d(0,0,0);
-	}
-.leaflet-tile, 
-.leaflet-marker-icon, 
-.leaflet-marker-shadow {
-	-moz-user-select: none;
-	-webkit-user-select: none;
-	user-select: none;
-	}
-.leaflet-marker-icon, 
-.leaflet-marker-shadow {
-	display: block;
-	}
-.leaflet-clickable {
-	cursor: pointer;
-	}
-.leaflet-container img {
-	max-width: auto;
-	}
-
-.leaflet-tile-pane { z-index: 2; }
-.leaflet-overlay-pane { z-index: 3; }
-.leaflet-shadow-pane { z-index: 4; }
-.leaflet-marker-pane { z-index: 5; }
-.leaflet-popup-pane { z-index: 6; }
-
-.leaflet-zoom-box {
-	width: 0;
-	height: 0;
-	}
-
-.leaflet-tile {
-	visibility: hidden;
-	}
-.leaflet-tile-loaded {
-	visibility: inherit;
-	}
-
-a.leaflet-active {
-	outline: 2px solid orange;
-	}
-
-
-/* Leaflet controls */
-
-.leaflet-control {
-	position: relative;
-	z-index: 7;
-	}
-.leaflet-top,
-.leaflet-bottom {
-	position: absolute;
-	}
-.leaflet-top {
-	top: 0;
-	}
-.leaflet-right {
-	right: 0;
-	}
-.leaflet-bottom {
-	bottom: 0;
-	}	
-.leaflet-left {
-	left: 0;
-	}
-.leaflet-control {
-	float: left;
-	clear: both;
-	}
-.leaflet-right .leaflet-control {
-	float: right;
-	}
-.leaflet-top .leaflet-control {
-	margin-top: 10px;
-	}
-.leaflet-bottom .leaflet-control {
-	margin-bottom: 10px;
-	}
-.leaflet-left .leaflet-control {
-	margin-left: 10px;
-	}
-.leaflet-right .leaflet-control {
-	margin-right: 10px;
-	}
-
-.leaflet-control-zoom {
-	padding: 5px;
-	background: rgba(0, 0, 0, 0.25);
-	
-	-moz-border-radius: 7px;
-	-webkit-border-radius: 7px;
-	border-radius: 7px;
-	}
-.leaflet-control-zoom a {
-	display: block;
-	width: 19px;
-	height: 19px;
-	background-position: 50% 50%;
-	background-repeat: no-repeat;
-	background-color: rgba(255, 255, 255, 0.75);
-	
-	-moz-border-radius: 4px;
-	-webkit-border-radius: 4px;
-	border-radius: 4px;
-	}
-.leaflet-control-zoom a:hover {
-	background-color: #fff;
-	}
-.leaflet-big-buttons .leaflet-control-zoom a {
-	width: 27px;
-	height: 27px;
-	}
-.leaflet-control-zoom-in {
-	background-image: url(images/zoom-in.png);
-	margin-bottom: 5px;
-	}
-.leaflet-control-zoom-out {
-	background-image: url(images/zoom-out.png);
-	}
-	
-.leaflet-container .leaflet-control-attribution {
-	margin: 0;
-	padding: 0 5px;
-	
-	font: 11px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
-	color: #333;
-	
-	background-color: rgba(255, 255, 255, 0.7);
-            
-	-moz-box-shadow: 0 0 7px #ccc;
-	-webkit-box-shadow: 0 0 7px #ccc;
-	box-shadow: 0 0 7px #ccc;
-	}
-
-
-/* Fade animations */
-
-.leaflet-fade-anim .leaflet-tile {
-	opacity: 0;
-	
-	-webkit-transition: opacity 0.2s linear;
-	-moz-transition: opacity 0.2s linear;
-	-o-transition: opacity 0.2s linear;
-	transition: opacity 0.2s linear;
-	}
-.leaflet-fade-anim .leaflet-tile-loaded {
-	opacity: 1;
-	}
-
-.leaflet-fade-anim .leaflet-popup {
-	opacity: 0;
-
-	-webkit-transition: opacity 0.2s linear;
-	-moz-transition: opacity 0.2s linear;
-	-o-transition: opacity 0.2s linear;
-	transition: opacity 0.2s linear;
-	}
-.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
-	opacity: 1;
-	}
-
-.leaflet-zoom-anim .leaflet-tile {
-	-webkit-transition: none;
-	-moz-transition: none;
-	-o-transition: none;
-	transition: none;
-	}
-
-.leaflet-zoom-anim .leaflet-objects-pane {
-	visibility: hidden;
-	}
-
-
-/* Popup layout */
-
-.leaflet-popup {
-	position: absolute;
-	text-align: center;
-	-webkit-transform: translate3d(0,0,0);
-	}
-.leaflet-popup-content-wrapper {
-	padding: 1px;
-	text-align: left;
-	}
-.leaflet-popup-content {
-	margin: 19px;
-	}
-.leaflet-popup-tip-container {
-	margin: 0 auto;
-	width: 40px;
-	height: 16px;
-	position: relative;
-	overflow: hidden;
-	}
-.leaflet-popup-tip {
-	width: 15px;
-	height: 15px;
-	padding: 1px;
-	
-	margin: -8px auto 0;
-	
-	-moz-transform: rotate(45deg);
-	-webkit-transform: rotate(45deg);
-	-ms-transform: rotate(45deg);
-	-o-transform: rotate(45deg);
-	transform: rotate(45deg);
-	}
-.leaflet-popup-close-button {
-	position: absolute;
-	top: 9px;
-	right: 9px;
-	
-	width: 10px;
-	height: 10px;
-	
-	overflow: hidden;
-	}
-.leaflet-popup-content p {
-	margin: 18px 0;
-	}
-
-
-/* Visual appearance */
-
-.leaflet-container {
-	background: #ddd;
-	}
-.leaflet-container a {
-	color: #0078A8;
-	}
-.leaflet-zoom-box {
-	border: 2px dotted #05f;
-	background: white;
-	opacity: 0.5;
-	}
-.leaflet-popup-content-wrapper, .leaflet-popup-tip {
-	background: white;
-	
-	box-shadow: 0 1px 10px #888;
-	-moz-box-shadow: 0 1px 10px #888;
-	 -webkit-box-shadow: 0 1px 14px #999;
-	}
-.leaflet-popup-content-wrapper {
-	-moz-border-radius: 20px; 
-	-webkit-border-radius: 20px;
-	border-radius: 20px;
-	}
-.leaflet-popup-content {
-	font: 12px/1.4 "Helvetica Neue", Arial, Helvetica, sans-serif;
-	}
-.leaflet-popup-close-button {
-	background: white url(images/popup-close.png);
-	}
\ No newline at end of file


diff -r 632bff56e1e8431e91eb37188c2d8c92ad729d55 -r 054f19f0fe563c6c99b345b1c1f9e271d085f7b0 yt/gui/reason/html/resources/leaflet/leaflet.ie.css
--- a/yt/gui/reason/html/resources/leaflet/leaflet.ie.css
+++ /dev/null
@@ -1,46 +0,0 @@
-.leaflet-tile {
-	filter: inherit;
-	}
-
-.leaflet-vml-shape {
-	width: 1px;
-	height: 1px;
-	}
-.lvml {
-	behavior: url(#default#VML); 
-	display: inline-block; 
-	position: absolute;
-	}
-	
-.leaflet-control {
-	display: inline;
-	}
-
-.leaflet-popup-tip {
-	width: 21px;
-	_width: 27px;
-	margin: 0 auto;
-	_margin-top: -3px;
-	
-	filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
-	-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
-	}
-.leaflet-popup-tip-container {
-	margin-top: -1px;
-	}
-.leaflet-popup-content-wrapper, .leaflet-popup-tip {
-	border: 1px solid #bbb;
-	}
-
-.leaflet-control-zoom {
-	filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#3F000000',EndColorStr='#3F000000');
-	}
-.leaflet-control-zoom a {
-	background-color: #eee;
-	}
-.leaflet-control-zoom a:hover {
-	background-color: #fff;
-	}
-.leaflet-control-attribution {
-	filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#B2FFFFFF,endColorstr=#B2FFFFFF);
-	}
\ No newline at end of file


diff -r 632bff56e1e8431e91eb37188c2d8c92ad729d55 -r 054f19f0fe563c6c99b345b1c1f9e271d085f7b0 yt/gui/reason/html/resources/leaflet/leaflet.js
--- a/yt/gui/reason/html/resources/leaflet/leaflet.js
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- Copyright (c) 2010-2011, CloudMade, Vladimir Agafonkin
- Leaflet is a BSD-licensed JavaScript library for map display and interaction.
- See http://cloudmade.github.com/Leaflet/ for more information.
-*/
-(function(a){var b={VERSION:"0.2",ROOT_URL:function(){for(var a=document.getElementsByTagName("script"),b=/^(.*\/)leaflet-?([\w-]*)\.js.*$/,e=0,f=a.length;e<f;e++){var g=a[e].src;if(g=g&&g.match(b)){if(g[2]=="include")break;return g[1]}}return"../../dist/"}(),noConflict:function(){a.L=this._originalL;return this},_originalL:a.L};window.L=b})(this);L.Util={extend:function(a){for(var b=Array.prototype.slice.call(arguments,1),c=0,d=b.length,e;c<d;c++){e=b[c]||{};for(var f in e)e.hasOwnProperty(f)&&(a[f]=e[f])}return a},bind:function(a,b){return function(){return a.apply(b,arguments)}},stamp:function(){var a=0;return function(b){b._leaflet_id=b._leaflet_id||++a;return b._leaflet_id}}(),requestAnimFrame:function(){function a(a){window.setTimeout(a,1E3/60)}var b=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||
-window.oRequestAnimationFrame||window.msRequestAnimationFrame||a;return function(c,d,e){c=d?L.Util.bind(c,d):d;e&&b===a?c():b(c)}}(),limitExecByInterval:function(a,b,c){function d(){e=!1;f&&(g.callee.apply(c,g),f=!1)}var e,f,g;return function(){g=arguments;e?f=!0:(e=!0,setTimeout(d,b),a.apply(c,g))}},falseFn:function(){return!1},formatNum:function(a,b){var c=Math.pow(10,b||5);return Math.round(a*c)/c},setOptions:function(a,b){a.options=L.Util.extend({},a.options,b)},getParamString:function(a){var b=
-[],c;for(c in a)a.hasOwnProperty(c)&&b.push(c+"="+a[c]);return"?"+b.join("&")}};L.Class=function(){};
-L.Class.extend=function(a){var b=function(){!L.Class._prototyping&&this.initialize&&this.initialize.apply(this,arguments)};L.Class._prototyping=!0;var c=new this;L.Class._prototyping=!1;c.constructor=b;b.prototype=c;c.superclass=this.prototype;a.statics&&(L.Util.extend(b,a.statics),delete a.statics);a.includes&&(L.Util.extend.apply(null,[c].concat(a.includes)),delete a.includes);if(a.options&&c.options)a.options=L.Util.extend({},c.options,a.options);L.Util.extend(c,a);b.extend=arguments.callee;b.include=
-function(a){L.Util.extend(this.prototype,a)};for(var d in this)this.hasOwnProperty(d)&&d!="prototype"&&(b[d]=this[d]);return b};L.Mixin={};
-L.Mixin.Events={addEventListener:function(a,b,c){var d=this._leaflet_events=this._leaflet_events||{};d[a]=d[a]||[];d[a].push({action:b,context:c});return this},hasEventListeners:function(a){return"_leaflet_events"in this&&a in this._leaflet_events&&this._leaflet_events[a].length>0},removeEventListener:function(a,b,c){if(!this.hasEventListeners(a))return this;for(var d=0,e=this._leaflet_events,f=e[a].length;d<f;d++)if(e[a][d].action===b&&(!c||e[a][d].context===c)){e[a].splice(d,1);break}return this},fireEvent:function(a,
-b){if(this.hasEventListeners(a)){for(var c=L.Util.extend({type:a,target:this},b),d=this._leaflet_events[a].slice(),e=0,f=d.length;e<f;e++)d[e].action.call(d[e].context||this,c);return this}}};L.Mixin.Events.on=L.Mixin.Events.addEventListener;L.Mixin.Events.off=L.Mixin.Events.removeEventListener;L.Mixin.Events.fire=L.Mixin.Events.fireEvent;(function(){var a=navigator.userAgent.toLowerCase(),b=!!window.ActiveXObject,c=a.indexOf("webkit")!=-1,d=a.indexOf("mobi")!=-1,e=a.indexOf("android")!=-1,f=window.opera;L.Browser={ie:b,ie6:b&&!window.XMLHttpRequest,webkit:c,webkit3d:c&&"WebKitCSSMatrix"in window&&"m11"in new WebKitCSSMatrix,mobileWebkit:c&&(d||e),mobileOpera:d&&f,gecko:a.indexOf("gecko")!=-1,android:e};L.Browser.touch=L.Browser.mobileWebkit||L.Browser.mobileOpera})();L.Point=function(a,b,c){this.x=c?Math.round(a):a;this.y=c?Math.round(b):b};
-L.Point.prototype={add:function(a){return this.clone()._add(a)},_add:function(a){this.x+=a.x;this.y+=a.y;return this},subtract:function(a){return this.clone()._subtract(a)},_subtract:function(a){this.x-=a.x;this.y-=a.y;return this},divideBy:function(a,b){return new L.Point(this.x/a,this.y/a,b)},multiplyBy:function(a){return new L.Point(this.x*a,this.y*a)},distanceTo:function(a){var b=a.x-this.x,a=a.y-this.y;return Math.sqrt(b*b+a*a)},round:function(){return this.clone()._round()},_round:function(){this.x=
-Math.round(this.x);this.y=Math.round(this.y);return this},clone:function(){return new L.Point(this.x,this.y)},toString:function(){return"Point("+L.Util.formatNum(this.x)+", "+L.Util.formatNum(this.y)+")"}};L.Bounds=L.Class.extend({initialize:function(a,b){if(a)for(var c=a instanceof Array?a:[a,b],d=0,e=c.length;d<e;d++)this.extend(c[d])},extend:function(a){!this.min&&!this.max?(this.min=new L.Point(a.x,a.y),this.max=new L.Point(a.x,a.y)):(this.min.x=Math.min(a.x,this.min.x),this.max.x=Math.max(a.x,this.max.x),this.min.y=Math.min(a.y,this.min.y),this.max.y=Math.max(a.y,this.max.y))},getCenter:function(a){return new L.Point((this.min.x+this.max.x)/2,(this.min.y+this.max.y)/2,a)},contains:function(a){var b;
-if(a instanceof L.Bounds)b=a.min,a=a.max;return b.x>=this.min.x&&a.x<=this.max.x&&b.y>=this.min.y&&a.y<=this.max.y}});L.Transformation=L.Class.extend({initialize:function(a,b,c,d){this._a=a;this._b=b;this._c=c;this._d=d},transform:function(a,b){return this._transform(a.clone(),b)},_transform:function(a,b){b=b||1;a.x=b*(this._a*a.x+this._b);a.y=b*(this._c*a.y+this._d);return a},untransform:function(a,b){b=b||1;return new L.Point((a.x/b-this._b)/this._a,(a.y/b-this._d)/this._c)}});L.LineUtil={simplify:function(a,b){if(!b)return a.slice();a=this.reducePoints(a,b);return a=this.simplifyDP(a,b)},pointToSegmentDistance:function(a,b,c){return Math.sqrt(this._sqPointToSegmentDist(a,b,c))},simplifyDP:function(a,b){for(var c=0,d=0,e=b*b,f=1,g=a.length,h;f<g-1;f++)h=this._sqPointToSegmentDist(a[f],a[0],a[g-1]),h>c&&(d=f,c=h);return c>=e?(c=a.slice(0,d),d=a.slice(d),g=this.simplifyDP(c,b).slice(0,g-2),d=this.simplifyDP(d,b),g.concat(d)):[a[0],a[g-1]]},reducePoints:function(a,b){for(var c=
-[a[0]],d=b*b,e=1,f=0,g=a.length;e<g;e++)this._sqDist(a[e],a[f])<d||(c.push(a[e]),f=e);f<g-1&&c.push(a[g-1]);return c},clipSegment:function(a,b,c,d){var d=d?this._lastCode:this._getBitCode(a,c),e=this._getBitCode(b,c);for(this._lastCode=e;;)if(d|e)if(d&e)return!1;else{var f=d||e,g=this._getEdgeIntersection(a,b,f,c),h=this._getBitCode(g,c);f==d?(a=g,d=h):(b=g,e=h)}else return[a,b]},_getEdgeIntersection:function(a,b,c,d){var e=b.x-a.x,b=b.y-a.y,f=d.min,d=d.max;if(c&8)return new L.Point(a.x+e*(d.y-a.y)/
-b,d.y);else if(c&4)return new L.Point(a.x+e*(f.y-a.y)/b,f.y);else if(c&2)return new L.Point(d.x,a.y+b*(d.x-a.x)/e);else if(c&1)return new L.Point(f.x,a.y+b*(f.x-a.x)/e)},_getBitCode:function(a,b){var c=0;a.x<b.min.x?c|=1:a.x>b.max.x&&(c|=2);a.y<b.min.y?c|=4:a.y>b.max.y&&(c|=8);return c},_sqDist:function(a,b){var c=b.x-a.x,d=b.y-a.y;return c*c+d*d},_sqPointToSegmentDist:function(a,b,c){var d=c.x-b.x,e=c.y-b.y;if(!d&&!e)return this._sqDist(a,b);var f=((a.x-b.x)*d+(a.y-b.y)*e)/this._sqDist(b,c);if(f<
-0)return this._sqDist(a,b);if(f>1)return this._sqDist(a,c);b=new L.Point(b.x+d*f,b.y+e*f);return this._sqDist(a,b)}};L.PolyUtil={};L.PolyUtil.clipPolygon=function(a,b){var c,d=[1,4,2,8],e,f,g,h,j,k,l=L.LineUtil;e=0;for(j=a.length;e<j;e++)a[e]._code=l._getBitCode(a[e],b);for(g=0;g<4;g++){k=d[g];c=[];e=0;j=a.length;for(f=j-1;e<j;f=e++)if(h=a[e],f=a[f],h._code&k){if(!(f._code&k))f=l._getEdgeIntersection(f,h,k,b),f._code=l._getBitCode(f,b),c.push(f)}else{if(f._code&k)f=l._getEdgeIntersection(f,h,k,b),f._code=l._getBitCode(f,b),c.push(f);c.push(h)}a=c}return a};L.DomEvent={addListener:function(a,b,c,d){function e(b){return c.call(d||a,b||L.DomEvent._getEvent())}var f=L.Util.stamp(c);if(L.Browser.touch&&b=="dblclick"&&this.addDoubleTapListener)this.addDoubleTapListener(a,e,f);else if("addEventListener"in a)if(b=="mousewheel")a.addEventListener("DOMMouseScroll",e,!1),a.addEventListener(b,e,!1);else if(b=="mouseenter"||b=="mouseleave"){var g=e,e=function(b){if(L.DomEvent._checkMouse(a,b))return g(b)};a.addEventListener(b=="mouseenter"?"mouseover":"mouseout",
-e,!1)}else a.addEventListener(b,e,!1);else"attachEvent"in a&&a.attachEvent("on"+b,e);a["_leaflet_"+b+f]=e},removeListener:function(a,b,c){var c=L.Util.stamp(c),d="_leaflet_"+b+c;handler=a[d];L.Browser.mobileWebkit&&b=="dblclick"&&this.removeDoubleTapListener?this.removeDoubleTapListener(a,c):"removeEventListener"in a?b=="mousewheel"?(a.removeEventListener("DOMMouseScroll",handler,!1),a.removeEventListener(b,handler,!1)):b=="mouseenter"||b=="mouseleave"?a.removeEventListener(b=="mouseenter"?"mouseover":
-"mouseout",handler,!1):a.removeEventListener(b,handler,!1):"detachEvent"in a&&a.detachEvent("on"+b,handler);a[d]=null},_checkMouse:function(a,b){var c=b.relatedTarget;if(!c)return!0;try{for(;c&&c!=a;)c=c.parentNode}catch(d){return!1}return c!=a},_getEvent:function(){var a=window.event;if(!a)for(var b=arguments.callee.caller;b;){if((a=b.arguments[0])&&Event==a.constructor)break;b=b.caller}return a},stopPropagation:function(a){a.stopPropagation?a.stopPropagation():a.cancelBubble=!0},disableClickPropagation:function(a){L.DomEvent.addListener(a,
-"mousedown",L.DomEvent.stopPropagation);L.DomEvent.addListener(a,"click",L.DomEvent.stopPropagation);L.DomEvent.addListener(a,"dblclick",L.DomEvent.stopPropagation)},preventDefault:function(a){a.preventDefault?a.preventDefault():a.returnValue=!1},stop:function(a){L.DomEvent.preventDefault(a);L.DomEvent.stopPropagation(a)},getMousePosition:function(a,b){var c=new L.Point(a.pageX?a.pageX:a.clientX+document.body.scrollLeft+document.documentElement.scrollLeft,a.pageY?a.pageY:a.clientY+document.body.scrollTop+
-document.documentElement.scrollTop);return b?c.subtract(L.DomUtil.getCumulativeOffset(b)):c},getWheelDelta:function(a){var b=0;a.wheelDelta&&(b=a.wheelDelta/120);a.detail&&(b=-a.detail/3);return b}};L.Util.extend(L.DomEvent,{addDoubleTapListener:function(a,b,c){function d(a){if(a.touches.length==1){var b=Date.now(),c=b-(f||b);j=a.touches[0];g=c>0&&c<=h;f=b}}function e(){if(g)j.type="dblclick",b(j),f=null}var f,g=!1,h=250,j;a["_leaflet_touchstart"+c]=d;a["_leaflet_touchend"+c]=e;a.addEventListener("touchstart",d,!1);a.addEventListener("touchend",e,!1)},removeDoubleTapListener:function(a,b){a.removeEventListener(a,a["_leaflet_touchstart"+b],!1);a.removeEventListener(a,a["_leaflet_touchend"+b],
-!1)}});L.DomUtil={get:function(a){return typeof a=="string"?document.getElementById(a):a},getStyle:function(a,b){var c=a.style[b];!c&&a.currentStyle&&(c=a.currentStyle[b]);if(!c||c=="auto")c=(c=document.defaultView.getComputedStyle(a,null))?c[b]:null;return c=="auto"?null:c},getCumulativeOffset:function(a){var b=0,c=0;do b+=a.offsetTop||0,c+=a.offsetLeft||0,a=a.offsetParent;while(a);return new L.Point(c,b)},create:function(a,b,c){a=document.createElement(a);a.className=b;c&&c.appendChild(a);return a},disableTextSelection:function(){document.selection&&
-document.selection.empty&&document.selection.empty();if(!this._onselectstart)this._onselectstart=document.onselectstart,document.onselectstart=L.Util.falseFn},enableTextSelection:function(){document.onselectstart=this._onselectstart;this._onselectstart=null},CLASS_RE:/(\\s|^)'+cls+'(\\s|$)/,hasClass:function(a,b){return a.className.length>0&&RegExp("(^|\\s)"+b+"(\\s|$)").test(a.className)},addClass:function(a,b){L.DomUtil.hasClass(a,b)||(a.className+=(a.className?" ":"")+b)},setOpacity:function(a,
-b){L.Browser.ie?a.style.filter="alpha(opacity="+Math.round(b*100)+")":a.style.opacity=b},testProp:function(a){for(var b=document.documentElement.style,c=0;c<a.length;c++)if(a[c]in b)return a[c];return!1},getTranslateString:function(a){return L.DomUtil.TRANSLATE_OPEN+a.x+"px,"+a.y+"px"+L.DomUtil.TRANSLATE_CLOSE},getScaleString:function(a,b){return L.DomUtil.getTranslateString(b)+" scale("+a+") "+L.DomUtil.getTranslateString(b.multiplyBy(-1))},setPosition:function(a,b){a._leaflet_pos=b;L.Browser.webkit?
-a.style[L.DomUtil.TRANSFORM]=L.DomUtil.getTranslateString(b):(a.style.left=b.x+"px",a.style.top=b.y+"px")},getPosition:function(a){return a._leaflet_pos}};
-L.Util.extend(L.DomUtil,{TRANSITION:L.DomUtil.testProp(["transition","webkitTransition","OTransition","MozTransition","msTransition"]),TRANSFORM:L.DomUtil.testProp(["transformProperty","WebkitTransform","OTransform","MozTransform","msTransform"]),TRANSLATE_OPEN:"translate"+(L.Browser.webkit3d?"3d(":"("),TRANSLATE_CLOSE:L.Browser.webkit3d?",0)":")"});L.Draggable=L.Class.extend({includes:L.Mixin.Events,statics:{START:L.Browser.touch?"touchstart":"mousedown",END:L.Browser.touch?"touchend":"mouseup",MOVE:L.Browser.touch?"touchmove":"mousemove",TAP_TOLERANCE:15},initialize:function(a,b){this._element=a;this._dragStartTarget=b||a},enable:function(){if(!this._enabled)L.DomEvent.addListener(this._dragStartTarget,L.Draggable.START,this._onDown,this),this._enabled=!0},disable:function(){if(this._enabled)L.DomEvent.removeListener(this._dragStartTarget,
-L.Draggable.START,this._onDown),this._enabled=!1},_onDown:function(a){if(!(a.shiftKey||a.which!=1&&a.button!=1&&!a.touches)&&!(a.touches&&a.touches.length>1)){var b=a.touches&&a.touches.length==1?a.touches[0]:a;L.DomEvent.preventDefault(a);L.Browser.mobileWebkit&&(b.target.className+=" leaflet-active");this._moved=!1;L.DomUtil.disableTextSelection();this._setMovingCursor();this._startPos=this._newPos=L.DomUtil.getPosition(this._element);this._startPoint=new L.Point(b.clientX,b.clientY);L.DomEvent.addListener(document,
-L.Draggable.MOVE,this._onMove,this);L.DomEvent.addListener(document,L.Draggable.END,this._onUp,this)}},_onMove:function(a){if(!(a.touches&&a.touches.length>1)){L.DomEvent.preventDefault(a);a=a.touches&&a.touches.length==1?a.touches[0]:a;if(!this._moved)this.fire("dragstart"),this._moved=!0;this._newPos=this._startPos.add(new L.Point(a.clientX,a.clientY)).subtract(this._startPoint);L.Util.requestAnimFrame(this._updatePosition,this,!0);this.fire("drag")}},_updatePosition:function(){L.DomUtil.setPosition(this._element,
-this._newPos)},_onUp:function(a){if(a.changedTouches){var a=a.changedTouches[0],b=a.target,c=this._newPos&&this._newPos.distanceTo(this._startPos)||0;b.className=b.className.replace(" leaflet-active","");c<L.Draggable.TAP_TOLERANCE&&this._simulateEvent("click",a)}L.DomUtil.enableTextSelection();this._restoreCursor();L.DomEvent.removeListener(document,L.Draggable.MOVE,this._onMove);L.DomEvent.removeListener(document,L.Draggable.END,this._onUp);this._moved&&this.fire("dragend")},_removeActiveClass:function(){},
-_setMovingCursor:function(){this._bodyCursor=document.body.style.cursor;document.body.style.cursor="move"},_restoreCursor:function(){document.body.style.cursor=this._bodyCursor},_simulateEvent:function(a,b){var c=document.createEvent("MouseEvent");c.initMouseEvent(a,!0,!0,window,1,b.screenX,b.screenY,b.clientX,b.clientY,!1,!1,!1,!1,0,null);b.target.dispatchEvent(c)}});L.Transition=L.Class.extend({includes:L.Mixin.Events,statics:{CUSTOM_PROPS_SETTERS:{position:L.DomUtil.setPosition},implemented:function(){return L.Transition.NATIVE||L.Transition.TIMER}},options:{easing:"ease",duration:0.5},_setProperty:function(a,b){var c=L.Transition.CUSTOM_PROPS_SETTERS;if(a in c)c[a](this._el,b);else this._el.style[a]=b}});L.Transition=L.Transition.extend({statics:function(){var a=L.DomUtil.TRANSITION;return{NATIVE:!!a,TRANSITION:a,PROPERTY:a+"Property",DURATION:a+"Duration",EASING:a+"TimingFunction",END:a=="webkitTransition"||a=="OTransition"?a+"End":"transitionend",CUSTOM_PROPS_PROPERTIES:{position:L.Browser.webkit?L.DomUtil.TRANSFORM:"top, left"}}}(),options:{fakeStepInterval:100},initialize:function(a,b){this._el=a;L.Util.setOptions(this,b);L.DomEvent.addListener(a,L.Transition.END,this._onTransitionEnd,this);this._onFakeStep=
-L.Util.bind(this._onFakeStep,this)},run:function(a){var b,c=[],d=L.Transition.CUSTOM_PROPS_PROPERTIES;for(b in a)a.hasOwnProperty(b)&&(b=d[b]?d[b]:b,b=b.replace(/([A-Z])/g,function(a){return"-"+a.toLowerCase()}),c.push(b));this._el.style[L.Transition.DURATION]=this.options.duration+"s";this._el.style[L.Transition.EASING]=this.options.easing;this._el.style[L.Transition.PROPERTY]=c.join(", ");for(b in a)a.hasOwnProperty(b)&&this._setProperty(b,a[b]);this._inProgress=!0;this.fire("start");L.Transition.NATIVE?
-this._timer=setInterval(this._onFakeStep,this.options.fakeStepInterval):this._onTransitionEnd()},_onFakeStep:function(){this.fire("step")},_onTransitionEnd:function(){if(this._inProgress)this._inProgress=!1,clearInterval(this._timer),this._el.style[L.Transition.PROPERTY]="none",this.fire("step"),this.fire("end")}});L.Transition=L.Transition.NATIVE?L.Transition:L.Transition.extend({statics:{getTime:Date.now||function(){return+new Date},TIMER:!0,EASINGS:{ease:[0.25,0.1,0.25,1],linear:[0,0,1,1],"ease-in":[0.42,0,1,1],"ease-out":[0,0,0.58,1],"ease-in-out":[0.42,0,0.58,1]},CUSTOM_PROPS_GETTERS:{position:L.DomUtil.getPosition},UNIT_RE:/^[\d\.]+(\D*)$/},options:{fps:50},initialize:function(a,b){this._el=a;L.Util.extend(this.options,b);var c=L.Transition.EASINGS[this.options.easing]||L.Transition.EASINGS.ease;this._p1=
-new L.Point(0,0);this._p2=new L.Point(c[0],c[1]);this._p3=new L.Point(c[2],c[3]);this._p4=new L.Point(1,1);this._step=L.Util.bind(this._step,this);this._interval=Math.round(1E3/this.options.fps)},run:function(a){this._props={};var b=L.Transition.CUSTOM_PROPS_GETTERS,c=L.Transition.UNIT_RE;this.fire("start");for(var d in a)if(a.hasOwnProperty(d)){var e={};if(d in b)e.from=b[d](this._el);else{var f=this._el.style[d].match(c);e.from=parseFloat(f[0]);e.unit=f[1]}e.to=a[d];this._props[d]=e}clearInterval(this._timer);
-this._timer=setInterval(this._step,this._interval);this._startTime=L.Transition.getTime()},_step:function(){var a=L.Transition.getTime()-this._startTime,b=this.options.duration*1E3;a<b?this._runFrame(this._cubicBezier(a/b)):(this._runFrame(1),this._complete())},_runFrame:function(a){var b=L.Transition.CUSTOM_PROPS_SETTERS,c,d;for(c in this._props)this._props.hasOwnProperty(c)&&(d=this._props[c],c in b?(d=d.to.subtract(d.from).multiplyBy(a).add(d.from),b[c](this._el,d)):this._el.style[c]=(d.to-d.from)*
-a+d.from+d.unit);this.fire("step")},_complete:function(){clearInterval(this._timer);this.fire("end")},_cubicBezier:function(a){var b=3*Math.pow(1-a,2)*a,c=3*(1-a)*Math.pow(a,2),d=Math.pow(a,3),a=this._p1.multiplyBy(Math.pow(1-a,3)),b=this._p2.multiplyBy(b),c=this._p3.multiplyBy(c),d=this._p4.multiplyBy(d);return a.add(b).add(c).add(d).y}});L.LatLng=function(a,b,c){c!==!0&&(a=Math.max(Math.min(a,90),-90),b=(b+180)%360+(b<-180?180:-180));this.lat=a;this.lng=b};L.Util.extend(L.LatLng,{DEG_TO_RAD:Math.PI/180,RAD_TO_DEG:180/Math.PI,MAX_MARGIN:1.0E-9});L.LatLng.prototype={equals:function(a){if(!(a instanceof L.LatLng))return!1;return Math.max(Math.abs(this.lat-a.lat),Math.abs(this.lng-a.lng))<=L.LatLng.MAX_MARGIN},toString:function(){return"LatLng("+L.Util.formatNum(this.lat)+", "+L.Util.formatNum(this.lng)+")"}};L.LatLngBounds=L.Class.extend({initialize:function(a,b){if(a)for(var c=a instanceof Array?a:[a,b],d=0,e=c.length;d<e;d++)this.extend(c[d])},extend:function(a){!this._southWest&&!this._northEast?(this._southWest=new L.LatLng(a.lat,a.lng),this._northEast=new L.LatLng(a.lat,a.lng)):(this._southWest.lat=Math.min(a.lat,this._southWest.lat),this._southWest.lng=Math.min(a.lng,this._southWest.lng),this._northEast.lat=Math.max(a.lat,this._northEast.lat),this._northEast.lng=Math.max(a.lng,this._northEast.lng))},
-getCenter:function(){return new L.LatLng((this._southWest.lat+this._northEast.lat)/2,(this._southWest.lng+this._northEast.lng)/2)},getSouthWest:function(){return this._southWest},getNorthEast:function(){return this._northEast},getNorthWest:function(){return new L.LatLng(this._northEast.lat,this._southWest.lng)},getSouthEast:function(){return new L.LatLng(this._southWest.lat,this._northEast.lng)},contains:function(a){var b=this._southWest,c=this._northEast,d;a instanceof L.LatLngBounds?(d=a.getSouthWest(),
-a=a.getNorthEast()):d=a;return d.lat>=b.lat&&a.lat<=c.lat&&d.lng>=b.lng&&a.lng<=c.lng}});L.Projection={};L.Projection.SphericalMercator={MAX_LATITUDE:85.0511287798,project:function(a){var b=L.LatLng.DEG_TO_RAD,c=this.MAX_LATITUDE,d=a.lng*b,a=Math.max(Math.min(c,a.lat),-c)*b,a=Math.log(Math.tan(Math.PI/4+a/2));return new L.Point(d,a)},unproject:function(a,b){var c=L.LatLng.RAD_TO_DEG;return new L.LatLng((2*Math.atan(Math.exp(a.y))-Math.PI/2)*c,a.x*c,b)}};L.Projection.LonLat={project:function(a){return new L.Point(a.lng,a.lat)},unproject:function(a,b){return new L.LatLng(a.y,a.x,b)}};L.Projection.Mercator={MAX_LATITUDE:85.0840591556,R_MINOR:6356752.3142,R_MAJOR:6378137,project:function(a){var b=L.LatLng.DEG_TO_RAD,c=this.MAX_LATITUDE,d=this.R_MAJOR,e=a.lng*b*d,a=Math.max(Math.min(c,a.lat),-c)*b,b=this.R_MINOR/d,b=Math.sqrt(1-b*b),c=b*Math.sin(a),c=Math.pow((1-c)/(1+c),b*0.5),a=-d*Math.log(Math.tan(0.5*(Math.PI*0.5-a))/c);return new L.Point(e,a)},unproject:function(a,b){for(var c=L.LatLng.RAD_TO_DEG,d=this.R_MAJOR,e=a.x*c/d,f=this.R_MINOR/d,f=Math.sqrt(1-f*f),d=Math.exp(-a.y/d),
-g=Math.PI/2-2*Math.atan(d),h=15,j=0.1;Math.abs(j)>1.0E-7&&--h>0;)j=f*Math.sin(g),j=Math.PI/2-2*Math.atan(d*Math.pow((1-j)/(1+j),0.5*f))-g,g+=j;return new L.LatLng(g*c,e,b)}};L.CRS={latLngToPoint:function(a,b){return this.transformation._transform(this.projection.project(a),b)},pointToLatLng:function(a,b,c){return this.projection.unproject(this.transformation.untransform(a,b),c)},project:function(a){return this.projection.project(a)}};L.CRS.EPSG3857=L.Util.extend({},L.CRS,{code:"EPSG:3857",projection:L.Projection.SphericalMercator,transformation:new L.Transformation(0.5/Math.PI,0.5,-0.5/Math.PI,0.5),project:function(a){return this.projection.project(a).multiplyBy(6378137)}});L.CRS.EPSG900913=L.Util.extend({},L.CRS.EPSG3857,{code:"EPSG:900913"});L.CRS.EPSG4326=L.Util.extend({},L.CRS,{code:"EPSG:4326",projection:L.Projection.LonLat,transformation:new L.Transformation(1/360,0.5,-1/360,0.5)});L.CRS.EPSG3395=L.Util.extend({},L.CRS,{code:"EPSG:3395",projection:L.Projection.Mercator,transformation:function(){var a=L.Projection.Mercator;return new L.Transformation(0.5/(Math.PI*a.R_MAJOR),0.5,-0.5/(Math.PI*a.R_MINOR),0.5)}()});L.LayerGroup=L.Class.extend({initialize:function(a){this._layers={};if(a)for(var b=0,c=a.length;b<c;b++)this.addLayer(a[b])},addLayer:function(a){this._layers[L.Util.stamp(a)]=a;this._map&&this._map.addLayer(a);return this},removeLayer:function(a){delete this._layers[L.Util.stamp(a)];this._map&&this._map.removeLayer(a);return this},clearLayers:function(){this._iterateLayers(this.removeLayer,this);return this},onAdd:function(a){this._map=a;this._iterateLayers(a.addLayer,a)},onRemove:function(a){this._iterateLayers(a.removeLayer,
-a);delete this._map},_iterateLayers:function(a,b){for(var c in this._layers)this._layers.hasOwnProperty(c)&&a.call(b,this._layers[c])}});L.FeatureGroup=L.LayerGroup.extend({includes:L.Mixin.Events,addLayer:function(a){this._initEvents(a);L.LayerGroup.prototype.addLayer.call(this,a);this._popupContent&&a.bindPopup&&a.bindPopup(this._popupContent)},bindPopup:function(a){this._popupContent=a;for(var b in this._layers)this._layers.hasOwnProperty(b)&&this._layers[b].bindPopup&&this._layers[b].bindPopup(a)},_events:["click","dblclick","mouseover","mouseout"],_initEvents:function(a){for(var b=0,c=this._events.length;b<c;b++)a.on(this._events[b],
-this._propagateEvent,this)},_propagateEvent:function(a){a.layer=a.target;a.target=this;this.fire(a.type,a)}});L.TileLayer=L.Class.extend({includes:L.Mixin.Events,options:{minZoom:0,maxZoom:18,tileSize:256,subdomains:"abc",errorTileUrl:"",attribution:"",opacity:1,scheme:"xyz",noWrap:!1,unloadInvisibleTiles:L.Browser.mobileWebkit,updateWhenIdle:L.Browser.mobileWebkit},initialize:function(a,b){L.Util.setOptions(this,b);this._url=a;if(typeof this.options.subdomains=="string")this.options.subdomains=this.options.subdomains.split("")},onAdd:function(a){this._map=a;this._initContainer();this._createTileProto();
-a.on("viewreset",this._reset,this);if(this.options.updateWhenIdle)a.on("moveend",this._update,this);else this._limitedUpdate=L.Util.limitExecByInterval(this._update,100,this),a.on("move",this._limitedUpdate,this);this._reset();this._update()},onRemove:function(){this._map.getPanes().tilePane.removeChild(this._container);this._container=null;this._map.off("viewreset",this._reset,this);this.options.updateWhenIdle?this._map.off("moveend",this._update,this):this._map.off("move",this._limitedUpdate,this)},
-getAttribution:function(){return this.options.attribution},setOpacity:function(a){this.options.opacity=a;this._setOpacity(a);if(L.Browser.webkit)for(i in this._tiles)this._tiles[i].style.webkitTransform+=" translate(0,0)"},_setOpacity:function(a){a<1&&L.DomUtil.setOpacity(this._container,a)},_initContainer:function(){var a=this._map.getPanes().tilePane;if(!this._container||a.empty)this._container=L.DomUtil.create("div","leaflet-layer",a),this._setOpacity(this.options.opacity)},_reset:function(){this._tiles=
-{};this._initContainer();this._container.innerHTML=""},_update:function(){var a=this._map.getPixelBounds(),b=this.options.tileSize,c=new L.Point(Math.floor(a.min.x/b),Math.floor(a.min.y/b)),a=new L.Point(Math.floor(a.max.x/b),Math.floor(a.max.y/b)),c=new L.Bounds(c,a);this._addTilesFromCenterOut(c);this.options.unloadInvisibleTiles&&this._removeOtherTiles(c)},_addTilesFromCenterOut:function(a){for(var b=[],c=a.getCenter(),d=a.min.y;d<=a.max.y;d++)for(var e=a.min.x;e<=a.max.x;e++)e+":"+d in this._tiles||
-b.push(new L.Point(e,d));b.sort(function(a,b){return a.distanceTo(c)-b.distanceTo(c)});this._tilesToLoad=b.length;a=0;for(d=this._tilesToLoad;a<d;a++)this._addTile(b[a])},_removeOtherTiles:function(a){var b,c,d;for(d in this._tiles)if(this._tiles.hasOwnProperty(d)&&(b=d.split(":"),c=parseInt(b[0],10),b=parseInt(b[1],10),c<a.min.x||c>a.max.x||b<a.min.y||b>a.max.y))this._tiles[d].src="",this._tiles[d].parentNode==this._container&&this._container.removeChild(this._tiles[d]),delete this._tiles[d]},_addTile:function(a){var b=
-this._getTilePos(a),c=this._map.getZoom(),d=a.x+":"+a.y,e=1<<c;if(!this.options.noWrap)a.x=(a.x%e+e)%e;if(!(a.y<0||a.y>=e)){var f=this._createTile();L.DomUtil.setPosition(f,b);this._tiles[d]=f;if(this.options.scheme=="tms")a.y=e-a.y-1;this._loadTile(f,a,c);this._container.appendChild(f)}},_getTilePos:function(a){var b=this._map.getPixelOrigin();return a.multiplyBy(this.options.tileSize).subtract(b)},getTileUrl:function(a,b){return this._url.replace("{s}",this.options.subdomains[(a.x+a.y)%this.options.subdomains.length]).replace("{z}",
-b).replace("{x}",a.x).replace("{y}",a.y)},_createTileProto:function(){this._tileImg=L.DomUtil.create("img","leaflet-tile");this._tileImg.galleryimg="no";var a=this.options.tileSize;this._tileImg.style.width=a+"px";this._tileImg.style.height=a+"px"},_createTile:function(){var a=this._tileImg.cloneNode(!1);a.onselectstart=a.onmousemove=L.Util.falseFn;return a},_loadTile:function(a,b,c){a._layer=this;a.onload=this._tileOnLoad;a.onerror=this._tileOnError;a.src=this.getTileUrl(b,c)},_tileOnLoad:function(){var a=
-this._layer;this.className+=" leaflet-tile-loaded";a.fire("tileload",{tile:this,url:this.src});a._tilesToLoad--;a._tilesToLoad||a.fire("load")},_tileOnError:function(){var a=this._layer;a.fire("tileerror",{tile:this,url:this.src});if(a=a.options.errorTileUrl)this.src=a}});L.TileLayer.WMS=L.TileLayer.extend({defaultWmsParams:{service:"WMS",request:"GetMap",version:"1.1.1",layers:"",styles:"",format:"image/jpeg",transparent:!1},initialize:function(a,b){this._url=a;this.wmsParams=L.Util.extend({},this.defaultWmsParams);this.wmsParams.width=this.wmsParams.height=this.options.tileSize;for(var c in b)this.options.hasOwnProperty(c)||(this.wmsParams[c]=b[c]);L.Util.setOptions(this,b)},onAdd:function(a){this.wmsParams[parseFloat(this.wmsParams.version)>=1.3?"crs":"srs"]=a.options.crs.code;
-L.TileLayer.prototype.onAdd.call(this,a)},getTileUrl:function(a){var b=this.options.tileSize,a=a.multiplyBy(b),b=a.add(new L.Point(b,b)),a=this._map.unproject(a,this._zoom,!0),b=this._map.unproject(b,this._zoom,!0),a=this._map.options.crs.project(a),b=this._map.options.crs.project(b),b=[a.x,b.y,b.x,a.y].join(",");return this._url+L.Util.getParamString(this.wmsParams)+"&bbox="+b}});L.TileLayer.Canvas=L.TileLayer.extend({options:{async:!1},initialize:function(a){L.Util.setOptions(this,a)},_createTileProto:function(){this._canvasProto=L.DomUtil.create("canvas","leaflet-tile");var a=this.options.tileSize;this._canvasProto.width=a;this._canvasProto.height=a},_createTile:function(){var a=this._canvasProto.cloneNode(!1);a.onselectstart=a.onmousemove=L.Util.falseFn;return a},_loadTile:function(a,b,c){a._layer=this;this.drawTile(a,b,c);this.options.async||this.tileDrawn(a)},drawTile:function(){},
-tileDrawn:function(a){this._tileOnLoad.call(a)}});L.ImageOverlay=L.Class.extend({includes:L.Mixin.Events,initialize:function(a,b){this._url=a;this._bounds=b},onAdd:function(a){this._map=a;this._image||this._initImage();a.getPanes().overlayPane.appendChild(this._image);a.on("viewreset",this._reset,this);this._reset()},onRemove:function(a){a.getPanes().overlayPane.removeChild(this._image);a.off("viewreset",this._reset,this)},_initImage:function(){this._image=L.DomUtil.create("img","leaflet-image-layer");this._image.style.visibility="hidden";L.Util.extend(this._image,
-{galleryimg:"no",onselectstart:L.Util.falseFn,onmousemove:L.Util.falseFn,onload:this._onImageLoad,src:this._url})},_reset:function(){var a=this._map.latLngToLayerPoint(this._bounds.getNorthWest()),b=this._map.latLngToLayerPoint(this._bounds.getSouthEast()).subtract(a);L.DomUtil.setPosition(this._image,a);this._image.style.width=b.x+"px";this._image.style.height=b.y+"px"},_onImageLoad:function(){this.style.visibility=""}});L.Popup=L.Class.extend({includes:L.Mixin.Events,options:{maxWidth:300,autoPan:!0,closeButton:!0,offset:new L.Point(0,2),autoPanPadding:new L.Point(5,5)},initialize:function(a){L.Util.setOptions(this,a)},onAdd:function(a){this._map=a;this._container||this._initLayout();this._updateContent();this._container.style.opacity="0";this._map._panes.popupPane.appendChild(this._container);this._map.on("viewreset",this._updatePosition,this);if(this._map.options.closePopupOnClick)this._map.on("preclick",this._close,
-this);this._update();this._container.style.opacity="1";this._opened=!0},onRemove:function(a){a._panes.popupPane.removeChild(this._container);a.off("viewreset",this._updatePosition,this);a.off("click",this._close,this);this._container.style.opacity="0";this._opened=!1},setLatLng:function(a){this._latlng=a;this._opened&&this._update();return this},setContent:function(a){this._content=a;this._opened&&this._update();return this},_close:function(){this._opened&&this._map.removeLayer(this)},_initLayout:function(){this._container=
-L.DomUtil.create("div","leaflet-popup");this._closeButton=L.DomUtil.create("a","leaflet-popup-close-button",this._container);this._closeButton.href="#close";this._closeButton.onclick=L.Util.bind(this._onCloseButtonClick,this);this._wrapper=L.DomUtil.create("div","leaflet-popup-content-wrapper",this._container);L.DomEvent.disableClickPropagation(this._wrapper);this._contentNode=L.DomUtil.create("div","leaflet-popup-content",this._wrapper);this._tipContainer=L.DomUtil.create("div","leaflet-popup-tip-container",
-this._container);this._tip=L.DomUtil.create("div","leaflet-popup-tip",this._tipContainer)},_update:function(){this._container.style.visibility="hidden";this._updateContent();this._updateLayout();this._updatePosition();this._container.style.visibility="";this._adjustPan()},_updateContent:function(){if(this._content)typeof this._content=="string"?this._contentNode.innerHTML=this._content:(this._contentNode.innerHTML="",this._contentNode.appendChild(this._content))},_updateLayout:function(){this._container.style.width=
-"";this._container.style.whiteSpace="nowrap";var a=this._container.offsetWidth;this._container.style.width=(a>this.options.maxWidth?this.options.maxWidth:a)+"px";this._container.style.whiteSpace="";this._containerWidth=this._container.offsetWidth},_updatePosition:function(){var a=this._map.latLngToLayerPoint(this._latlng);this._containerBottom=-a.y-this.options.offset.y;this._containerLeft=a.x-Math.round(this._containerWidth/2)+this.options.offset.x;this._container.style.bottom=this._containerBottom+
-"px";this._container.style.left=this._containerLeft+"px"},_adjustPan:function(){if(this.options.autoPan){var a=this._container.offsetHeight,b=this._map.layerPointToContainerPoint(new L.Point(this._containerLeft,-a-this._containerBottom)),c=new L.Point(0,0),d=this.options.autoPanPadding,e=this._map.getSize();if(b.x<0)c.x=b.x-d.x;if(b.x+this._containerWidth>e.x)c.x=b.x+this._containerWidth-e.x+d.x;if(b.y<0)c.y=b.y-d.y;if(b.y+a>e.y)c.y=b.y+a-e.y+d.y;(c.x||c.y)&&this._map.panBy(c)}},_onCloseButtonClick:function(a){this._close();
-L.DomEvent.stop(a)}});L.Icon=L.Class.extend({iconUrl:L.ROOT_URL+"images/marker.png",shadowUrl:L.ROOT_URL+"images/marker-shadow.png",iconSize:new L.Point(25,41),shadowSize:new L.Point(41,41),iconAnchor:new L.Point(13,41),popupAnchor:new L.Point(0,-33),initialize:function(a){if(a)this.iconUrl=a},createIcon:function(){return this._createIcon("icon")},createShadow:function(){return this._createIcon("shadow")},_createIcon:function(a){var b=this[a+"Size"],c=this[a+"Url"],d=this._createImg(c);if(!c)return null;d.className="leaflet-marker-"+
-a;d.style.marginLeft=-this.iconAnchor.x+"px";d.style.marginTop=-this.iconAnchor.y+"px";if(b)d.style.width=b.x+"px",d.style.height=b.y+"px";return d},_createImg:function(a){var b;L.Browser.ie6?(b=document.createElement("div"),b.style.filter='progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+a+'")'):(b=document.createElement("img"),b.src=a);return b}});L.Marker=L.Class.extend({includes:L.Mixin.Events,options:{icon:new L.Icon,title:"",clickable:!0,draggable:!1},initialize:function(a,b){L.Util.setOptions(this,b);this._latlng=a},onAdd:function(a){this._map=a;this._initIcon();a.on("viewreset",this._reset,this);this._reset()},onRemove:function(a){this._removeIcon();a.off("viewreset",this._reset,this)},getLatLng:function(){return this._latlng},setLatLng:function(a){this._latlng=a;this._reset()},setIcon:function(a){this._removeIcon();this._icon=this._shadow=
-null;this.options.icon=a;this._initIcon()},_initIcon:function(){if(!this._icon){this._icon=this.options.icon.createIcon();if(this.options.title)this._icon.title=this.options.title;this._initInteraction()}if(!this._shadow)this._shadow=this.options.icon.createShadow();this._map._panes.markerPane.appendChild(this._icon);this._shadow&&this._map._panes.shadowPane.appendChild(this._shadow)},_removeIcon:function(){this._map._panes.markerPane.removeChild(this._icon);this._shadow&&this._map._panes.shadowPane.removeChild(this._shadow)},
-_reset:function(){var a=this._map.latLngToLayerPoint(this._latlng).round();L.DomUtil.setPosition(this._icon,a);this._shadow&&L.DomUtil.setPosition(this._shadow,a);this._icon.style.zIndex=a.y},_initInteraction:function(){if(this.options.clickable){this._icon.className+=" leaflet-clickable";L.DomEvent.addListener(this._icon,"click",this._onMouseClick,this);for(var a=["dblclick","mousedown","mouseover","mouseout"],b=0;b<a.length;b++)L.DomEvent.addListener(this._icon,a[b],this._fireMouseEvent,this)}if(L.Handler.MarkerDrag)this.dragging=
-new L.Handler.MarkerDrag(this),this.options.draggable&&this.dragging.enable()},_onMouseClick:function(a){L.DomEvent.stopPropagation(a);(!this.dragging||!this.dragging.moved())&&this.fire(a.type)},_fireMouseEvent:function(a){this.fire(a.type);L.DomEvent.stopPropagation(a)}});L.Marker.include({openPopup:function(){this._popup.setLatLng(this._latlng);this._map.openPopup(this._popup);return this},closePopup:function(){this._popup&&this._popup._close()},bindPopup:function(a,b){b=L.Util.extend({offset:this.options.icon.popupAnchor},b);this._popup=new L.Popup(b);this._popup.setContent(a);this.on("click",this.openPopup,this);return this}});L.Path=L.Class.extend({includes:[L.Mixin.Events],statics:function(){return{SVG_NS:"http://www.w3.org/2000/svg",SVG:!(!document.createElementNS||!document.createElementNS("http://www.w3.org/2000/svg","svg").createSVGRect),CLIP_PADDING:0.5}}(),options:{stroke:!0,color:"#0033ff",weight:5,opacity:0.5,fill:!1,fillColor:null,fillOpacity:0.2,clickable:!0,updateOnMoveEnd:!1},initialize:function(a){L.Util.setOptions(this,a)},onAdd:function(a){this._map=a;this._initElements();this._initEvents();this.projectLatlngs();
-this._updatePath();a.on("viewreset",this.projectLatlngs,this);this._updateTrigger=this.options.updateOnMoveEnd?"moveend":"viewreset";a.on(this._updateTrigger,this._updatePath,this)},onRemove:function(a){a._pathRoot.removeChild(this._container);a.off("viewreset",this._projectLatlngs,this);a.off(this._updateTrigger,this._updatePath,this)},projectLatlngs:function(){},getPathString:function(){},setStyle:function(a){L.Util.setOptions(this,a);this._path&&this._updateStyle()},_initElements:function(){this._initRoot();
-this._initPath();this._initStyle()},_initRoot:function(){if(!this._map._pathRoot)this._map._pathRoot=this._createElement("svg"),this._map._panes.overlayPane.appendChild(this._map._pathRoot),this._map.on("moveend",this._updateSvgViewport,this),this._updateSvgViewport()},_updateSvgViewport:function(){this._updateViewport();var a=this._map._pathViewport,b=a.min,c=a.max,a=c.x-b.x,c=c.y-b.y,d=this._map._pathRoot,e=this._map._panes.overlayPane;L.Browser.mobileWebkit&&e.removeChild(d);L.DomUtil.setPosition(d,
-b);d.setAttribute("width",a);d.setAttribute("height",c);d.setAttribute("viewBox",[b.x,b.y,a,c].join(" "));L.Browser.mobileWebkit&&e.appendChild(d)},_updateViewport:function(){var a=L.Path.CLIP_PADDING,b=this._map.getSize(),c=L.DomUtil.getPosition(this._map._mapPane).multiplyBy(-1).subtract(b.multiplyBy(a)),a=c.add(b.multiplyBy(1+a*2));this._map._pathViewport=new L.Bounds(c,a)},_initPath:function(){this._container=this._createElement("g");this._path=this._createElement("path");this._container.appendChild(this._path);
-this._map._pathRoot.appendChild(this._container)},_initStyle:function(){this.options.stroke&&(this._path.setAttribute("stroke-linejoin","round"),this._path.setAttribute("stroke-linecap","round"));this.options.fill?this._path.setAttribute("fill-rule","evenodd"):this._path.setAttribute("fill","none");this._updateStyle()},_updateStyle:function(){this.options.stroke&&(this._path.setAttribute("stroke",this.options.color),this._path.setAttribute("stroke-opacity",this.options.opacity),this._path.setAttribute("stroke-width",
-this.options.weight));this.options.fill&&(this._path.setAttribute("fill",this.options.fillColor||this.options.color),this._path.setAttribute("fill-opacity",this.options.fillOpacity))},_updatePath:function(){var a=this.getPathString();a||(a="M0 0");this._path.setAttribute("d",a)},_createElement:function(a){return document.createElementNS(L.Path.SVG_NS,a)},_initEvents:function(){if(this.options.clickable){L.Path.VML||this._path.setAttribute("class","leaflet-clickable");L.DomEvent.addListener(this._container,
-"click",this._onMouseClick,this);for(var a=["dblclick","mousedown","mouseover","mouseout"],b=0;b<a.length;b++)L.DomEvent.addListener(this._container,a[b],this._fireMouseEvent,this)}},_onMouseClick:function(a){(!this._map.dragging||!this._map.dragging.moved())&&this._fireMouseEvent(a)},_fireMouseEvent:function(a){this.hasEventListeners(a.type)&&(this.fire(a.type,{latlng:this._map.mouseEventToLatLng(a),layerPoint:this._map.mouseEventToLayerPoint(a)}),L.DomEvent.stopPropagation(a))},_redraw:function(){this.projectLatlngs();
-this._updatePath()}});L.Path.VML=function(){var a=document.createElement("div");a.innerHTML='<v:shape adj="1"/>';a=a.firstChild;a.style.behavior="url(#default#VML)";return a&&typeof a.adj=="object"}();
-L.Path=L.Path.SVG||!L.Path.VML?L.Path:L.Path.extend({statics:{CLIP_PADDING:0.02},_createElement:function(){try{return document.namespaces.add("lvml","urn:schemas-microsoft-com:vml"),function(a){return document.createElement("<lvml:"+a+' class="lvml">')}}catch(a){return function(a){return document.createElement("<"+a+' xmlns="urn:schemas-microsoft.com:vml" class="lvml">')}}}(),_initRoot:function(){if(!this._map._pathRoot)this._map._pathRoot=document.createElement("div"),this._map._pathRoot.className=
-"leaflet-vml-container",this._map._panes.overlayPane.appendChild(this._map._pathRoot),this._map.on("moveend",this._updateViewport,this),this._updateViewport()},_initPath:function(){this._container=this._createElement("shape");this._container.className+=" leaflet-vml-shape"+(this.options.clickable?" leaflet-clickable":"");this._container.coordsize="1 1";this._path=this._createElement("path");this._container.appendChild(this._path);this._map._pathRoot.appendChild(this._container)},_initStyle:function(){this.options.stroke?
-(this._stroke=this._createElement("stroke"),this._stroke.endcap="round",this._container.appendChild(this._stroke)):this._container.stroked=!1;this.options.fill?(this._container.filled=!0,this._fill=this._createElement("fill"),this._container.appendChild(this._fill)):this._container.filled=!1;this._updateStyle()},_updateStyle:function(){if(this.options.stroke)this._stroke.weight=this.options.weight+"px",this._stroke.color=this.options.color,this._stroke.opacity=this.options.opacity;if(this.options.fill)this._fill.color=
-this.options.fillColor||this.options.color,this._fill.opacity=this.options.fillOpacity},_updatePath:function(){this._container.style.display="none";this._path.v=this.getPathString()+" ";this._container.style.display=""}});L.Path.include({bindPopup:function(a,b){if(!this._popup||this._popup.options!==b)this._popup=new L.Popup(b);this._popup.setContent(a);if(!this._openPopupAdded)this.on("click",this._openPopup,this),this._openPopupAdded=!0;return this},_openPopup:function(a){this._popup.setLatLng(a.latlng);this._map.openPopup(this._popup)}});L.Polyline=L.Path.extend({initialize:function(a,b){L.Path.prototype.initialize.call(this,b);this._latlngs=a},options:{smoothFactor:1,noClip:!1,updateOnMoveEnd:!0},projectLatlngs:function(){this._originalPoints=[];for(var a=0,b=this._latlngs.length;a<b;a++)this._originalPoints[a]=this._map.latLngToLayerPoint(this._latlngs[a])},getPathString:function(){for(var a=0,b=this._parts.length,c="";a<b;a++)c+=this._getPathPartStr(this._parts[a]);return c},getLatLngs:function(){return this._latlngs},setLatLngs:function(a){this._latlngs=
-a;this._redraw();return this},addLatLng:function(a){this._latlngs.push(a);this._redraw();return this},spliceLatLngs:function(){var a=[].splice.apply(this._latlngs,arguments);this._redraw();return a},_getPathPartStr:function(a){for(var b=L.Path.VML,c=0,d=a.length,e="",f;c<d;c++)f=a[c],b&&f._round(),e+=(c?"L":"M")+f.x+" "+f.y;return e},_clipPoints:function(){var a=this._originalPoints,b=a.length,c,d,e;if(this.options.noClip)this._parts=[a];else{var f=this._parts=[],g=this._map._pathViewport,h=L.LineUtil;
-for(d=c=0;c<b-1;c++)if(e=h.clipSegment(a[c],a[c+1],g,c))if(f[d]=f[d]||[],f[d].push(e[0]),e[1]!=a[c+1]||c==b-2)f[d].push(e[1]),d++}},_simplifyPoints:function(){for(var a=this._parts,b=L.LineUtil,c=0,d=a.length;c<d;c++)a[c]=b.simplify(a[c],this.options.smoothFactor)},_updatePath:function(){this._clipPoints();this._simplifyPoints();L.Path.prototype._updatePath.call(this)}});L.Polygon=L.Polyline.extend({options:{fill:!0},initialize:function(a,b){L.Polyline.prototype.initialize.call(this,a,b);if(a[0]instanceof Array)this._latlngs=a[0],this._holes=a.slice(1)},projectLatlngs:function(){L.Polyline.prototype.projectLatlngs.call(this);this._holePoints=[];if(this._holes)for(var a=0,b=this._holes.length;a<b;a++){this._holePoints[a]=[];for(var c=0,d=this._holes[a].length;c<d;c++)this._holePoints[a][c]=this._map.latLngToLayerPoint(this._holes[a][c])}},_clipPoints:function(){var a=
-[];this._parts=[this._originalPoints].concat(this._holePoints);if(!this.options.noClip){for(var b=0,c=this._parts.length;b<c;b++){var d=L.PolyUtil.clipPolygon(this._parts[b],this._map._pathViewport);d.length&&a.push(d)}this._parts=a}},_getPathPartStr:function(a){return L.Polyline.prototype._getPathPartStr.call(this,a)+(L.Path.SVG?"z":"x")}});(function(){function a(a){return L.FeatureGroup.extend({initialize:function(c,d){this._layers={};for(var e=0,f=c.length;e<f;e++)this.addLayer(new a(c[e],d))},setStyle:function(a){for(var b in this._layers)this._layers.hasOwnProperty(b)&&this._layers[b].setStyle&&this._layers[b].setStyle(a)}})}L.MultiPolyline=a(L.Polyline);L.MultiPolygon=a(L.Polygon)})();L.Circle=L.Path.extend({initialize:function(a,b,c){L.Path.prototype.initialize.call(this,c);this._latlng=a;this._mRadius=b},options:{fill:!0},setLatLng:function(a){this._latlng=a;this._redraw();return this},setRadius:function(a){this._mRadius=a;this._redraw();return this},projectLatlngs:function(){var a=this._map.options.scale(this._map._zoom);this._point=this._map.latLngToLayerPoint(this._latlng);this._radius=this._mRadius/40075017*a},getPathString:function(){var a=this._point,b=this._radius;return L.Path.SVG?
-"M"+a.x+","+(a.y-b)+"A"+b+","+b+",0,1,1,"+(a.x-0.1)+","+(a.y-b)+" z":(a._round(),b=Math.round(b),"AL "+a.x+","+a.y+" "+b+","+b+" 0,23592600")}});L.CircleMarker=L.Circle.extend({options:{radius:10,weight:2},initialize:function(a,b){L.Circle.prototype.initialize.call(this,a,null,b);this._radius=this.options.radius},projectLatlngs:function(){this._point=this._map.latLngToLayerPoint(this._latlng)},setRadius:function(a){this._radius=a;this._redraw();return this}});L.GeoJSON=L.LayerGroup.extend({includes:L.Mixin.Events,initialize:function(a,b){L.Util.setOptions(this,b);this._geojson=a;this._layers={};a&&this.addGeoJSON(a)},addGeoJSON:function(a){if(a.features)for(var b=0,c=a.features.length;b<c;b++)this.addGeoJSON(a.features[b]);else b=a.type=="Feature"?a.geometry:a,c=L.GeoJSON.geometryToLayer(b,this.options.pointToLayer),this.fire("featureparse",{layer:c,properties:a.properties,geometryType:b.type,bbox:a.bbox,id:a.id}),this.addLayer(c)}});
-L.Util.extend(L.GeoJSON,{geometryToLayer:function(a,b){var c=a.coordinates,d,e,f,g=[];switch(a.type){case "Point":return d=this.coordsToLatLng(c),b?b(d):new L.Marker(d);case "MultiPoint":e=0;for(f=c.length;e<f;e++)d=this.coordsToLatLng(c[e]),d=b?b(d):new L.Marker(d),g.push(d);return new L.FeatureGroup(g);case "LineString":return c=this.coordsToLatLngs(c),new L.Polyline(c);case "Polygon":return c=this.coordsToLatLngs(c,1),new L.Polygon(c);case "MultiLineString":return c=this.coordsToLatLngs(c,1),new L.MultiPolyline(c);
-case "MultiPolygon":return c=this.coordsToLatLngs(c,2),new L.MultiPolygon(c);case "GeometryCollection":e=0;for(f=a.geometries.length;e<f;e++)d=this.geometryToLayer(a.geometries[e]),g.push(d);return new L.FeatureGroup(g);default:throw Error("Invalid GeoJSON object.");}},coordsToLatLng:function(a,b){var c=parseFloat(a[b?0:1]),d=parseFloat(a[b?1:0]);return new L.LatLng(c,d)},coordsToLatLngs:function(a,b,c){var d,e=[],f,g=a.length;for(f=0;f<g;f++)d=b?this.coordsToLatLngs(a[f],b-1,c):this.coordsToLatLng(a[f],
-c),e.push(d);return e}});L.Handler=L.Class.extend({initialize:function(a){this._map=a},enabled:function(){return!!this._enabled}});L.Handler.MapDrag=L.Handler.extend({enable:function(){if(!this._enabled){if(!this._draggable)this._draggable=new L.Draggable(this._map._mapPane,this._map._container),this._draggable.on("dragstart",this._onDragStart,this),this._draggable.on("drag",this._onDrag,this),this._draggable.on("dragend",this._onDragEnd,this);this._draggable.enable();this._enabled=!0}},disable:function(){if(this._enabled)this._draggable.disable(),this._enabled=!1},moved:function(){return this._draggable._moved},_onDragStart:function(){this._map.fire("movestart");
-this._map.fire("dragstart")},_onDrag:function(){this._map.fire("move");this._map.fire("drag")},_onDragEnd:function(){this._map.fire("moveend");this._map.fire("dragend")}});L.Handler.TouchZoom=L.Handler.extend({enable:function(){if(L.Browser.mobileWebkit&&!this._enabled)L.DomEvent.addListener(this._map._container,"touchstart",this._onTouchStart,this),this._enabled=!0},disable:function(){if(this._enabled)L.DomEvent.removeListener(this._map._container,"touchstart",this._onTouchStart,this),this._enabled=!1},_onTouchStart:function(a){if(a.touches&&!(a.touches.length!=2||this._map._animatingZoom)){var b=this._map.mouseEventToLayerPoint(a.touches[0]),c=this._map.mouseEventToLayerPoint(a.touches[1]),
-d=this._map.containerPointToLayerPoint(this._map.getSize().divideBy(2));this._startCenter=b.add(c).divideBy(2,!0);this._startDist=b.distanceTo(c);this._moved=!1;this._zooming=!0;this._centerOffset=d.subtract(this._startCenter);L.DomEvent.addListener(document,"touchmove",this._onTouchMove,this);L.DomEvent.addListener(document,"touchend",this._onTouchEnd,this);L.DomEvent.preventDefault(a)}},_onTouchMove:function(a){if(a.touches&&a.touches.length==2){if(!this._moved)this._map._mapPane.className+=" leaflet-zoom-anim",
-this._map._prepareTileBg(),this._moved=!0;var b=this._map.mouseEventToLayerPoint(a.touches[0]),c=this._map.mouseEventToLayerPoint(a.touches[1]);this._scale=b.distanceTo(c)/this._startDist;this._delta=b.add(c).divideBy(2,!0).subtract(this._startCenter);this._map._tileBg.style.webkitTransform=[L.DomUtil.getTranslateString(this._delta),L.DomUtil.getScaleString(this._scale,this._startCenter)].join(" ");L.DomEvent.preventDefault(a)}},_onTouchEnd:function(){if(this._moved&&this._zooming){this._zooming=
-!1;var a=this._map.getZoom(),b=Math.log(this._scale)/Math.LN2,b=this._map._limitZoom(a+(b>0?Math.ceil(b):Math.floor(b))),a=b-a,c=this._centerOffset.subtract(this._delta).divideBy(this._scale),d=this._map.unproject(this._map.getPixelOrigin().add(this._startCenter).add(c));L.DomEvent.removeListener(document,"touchmove",this._onTouchMove);L.DomEvent.removeListener(document,"touchend",this._onTouchEnd);this._map._runAnimation(d,b,Math.pow(2,a)/this._scale,this._startCenter.add(c))}}});L.Handler.ScrollWheelZoom=L.Handler.extend({enable:function(){if(!this._enabled)L.DomEvent.addListener(this._map._container,"mousewheel",this._onWheelScroll,this),this._delta=0,this._enabled=!0},disable:function(){if(this._enabled)L.DomEvent.removeListener(this._map._container,"mousewheel",this._onWheelScroll),this._enabled=!1},_onWheelScroll:function(a){this._delta+=L.DomEvent.getWheelDelta(a);this._lastMousePos=this._map.mouseEventToContainerPoint(a);clearTimeout(this._timer);this._timer=setTimeout(L.Util.bind(this._performZoom,
-this),50);L.DomEvent.preventDefault(a)},_performZoom:function(){var a=Math.round(this._delta);this._delta=0;if(a){var b=this._getCenterForScrollWheelZoom(this._lastMousePos,a),a=this._map.getZoom()+a;this._map._limitZoom(a)!=this._map._zoom&&this._map.setView(b,a)}},_getCenterForScrollWheelZoom:function(a,b){var c=this._map.getPixelBounds().getCenter(),d=this._map.getSize().divideBy(2),d=a.subtract(d).multiplyBy(1-Math.pow(2,-b));return this._map.unproject(c.add(d),this._map._zoom,!0)}});L.Handler.DoubleClickZoom=L.Handler.extend({enable:function(){if(!this._enabled)this._map.on("dblclick",this._onDoubleClick,this._map),this._enabled=!0},disable:function(){if(this._enabled)this._map.off("dblclick",this._onDoubleClick,this._map),this._enabled=!1},_onDoubleClick:function(a){this.setView(a.latlng,this._zoom+1)}});L.Handler.ShiftDragZoom=L.Handler.extend({initialize:function(a){this._map=a;this._container=a._container;this._pane=a._panes.overlayPane},enable:function(){if(!this._enabled)L.DomEvent.addListener(this._container,"mousedown",this._onMouseDown,this),this._enabled=!0},disable:function(){if(this._enabled)L.DomEvent.removeListener(this._container,"mousedown",this._onMouseDown),this._enabled=!1},_onMouseDown:function(a){if(!a.shiftKey||a.which!=1&&a.button!=1)return!1;L.DomUtil.disableTextSelection();
-this._startLayerPoint=this._map.mouseEventToLayerPoint(a);this._box=L.DomUtil.create("div","leaflet-zoom-box",this._pane);L.DomUtil.setPosition(this._box,this._startLayerPoint);this._container.style.cursor="crosshair";L.DomEvent.addListener(document,"mousemove",this._onMouseMove,this);L.DomEvent.addListener(document,"mouseup",this._onMouseUp,this);L.DomEvent.preventDefault(a)},_onMouseMove:function(a){var b=this._map.mouseEventToLayerPoint(a),a=b.x-this._startLayerPoint.x,c=b.y-this._startLayerPoint.y,
-b=new L.Point(Math.min(b.x,this._startLayerPoint.x),Math.min(b.y,this._startLayerPoint.y));L.DomUtil.setPosition(this._box,b);this._box.style.width=Math.abs(a)-4+"px";this._box.style.height=Math.abs(c)-4+"px"},_onMouseUp:function(a){this._pane.removeChild(this._box);this._container.style.cursor="";L.DomUtil.enableTextSelection();L.DomEvent.removeListener(document,"mousemove",this._onMouseMove);L.DomEvent.removeListener(document,"mouseup",this._onMouseUp);a=this._map.mouseEventToLayerPoint(a);this._map.fitBounds(new L.LatLngBounds(this._map.layerPointToLatLng(this._startLayerPoint),
-this._map.layerPointToLatLng(a)))}});L.Handler.MarkerDrag=L.Handler.extend({initialize:function(a){this._marker=a},enable:function(){if(!this._enabled){if(!this._draggable)this._draggable=new L.Draggable(this._marker._icon,this._marker._icon),this._draggable.on("dragstart",this._onDragStart,this),this._draggable.on("drag",this._onDrag,this),this._draggable.on("dragend",this._onDragEnd,this);this._draggable.enable();this._enabled=!0}},disable:function(){if(this._enabled)this._draggable.disable(),this._enabled=!1},moved:function(){return this._draggable&&
-this._draggable._moved},_onDragStart:function(){this._marker.closePopup();this._marker.fire("movestart");this._marker.fire("dragstart")},_onDrag:function(){var a=L.DomUtil.getPosition(this._marker._icon);L.DomUtil.setPosition(this._marker._shadow,a);this._marker._latlng=this._marker._map.layerPointToLatLng(a);this._marker.fire("move");this._marker.fire("drag")},_onDragEnd:function(){this._marker.fire("moveend");this._marker.fire("dragend")}});L.Control={};L.Control.Position={TOP_LEFT:"topLeft",TOP_RIGHT:"topRight",BOTTOM_LEFT:"bottomLeft",BOTTOM_RIGHT:"bottomRight"};L.Control.Zoom=L.Class.extend({onAdd:function(a){this._map=a;this._container=L.DomUtil.create("div","leaflet-control-zoom");this._zoomInButton=this._createButton("Zoom in","leaflet-control-zoom-in",this._map.zoomIn,this._map);this._zoomOutButton=this._createButton("Zoom out","leaflet-control-zoom-out",this._map.zoomOut,this._map);this._container.appendChild(this._zoomInButton);this._container.appendChild(this._zoomOutButton)},getContainer:function(){return this._container},getPosition:function(){return L.Control.Position.TOP_LEFT},
-_createButton:function(a,b,c,d){var e=document.createElement("a");e.href="#";e.title=a;e.className=b;L.DomEvent.disableClickPropagation(e);L.DomEvent.addListener(e,"click",L.DomEvent.preventDefault);L.DomEvent.addListener(e,"click",c,d);return e}});L.Control.Attribution=L.Class.extend({onAdd:function(a){this._container=L.DomUtil.create("div","leaflet-control-attribution");this._map=a;this._prefix='Powered by <a href="http://leaflet.cloudmade.com">Leaflet</a>';this._attributions={};this._update()},getPosition:function(){return L.Control.Position.BOTTOM_RIGHT},getContainer:function(){return this._container},setPrefix:function(a){this._prefix=a},addAttribution:function(a){a&&(this._attributions[a]=!0,this._update())},removeAttribution:function(a){a&&
-(delete this._attributions[a],this._update())},_update:function(){if(this._map){var a=[],b;for(b in this._attributions)this._attributions.hasOwnProperty(b)&&a.push(b);b=[];this._prefix&&b.push(this._prefix);a.length&&b.push(a.join(", "));this._container.innerHTML=b.join(" — ")}}});L.Map=L.Class.extend({includes:L.Mixin.Events,options:{crs:L.CRS.EPSG3857||L.CRS.EPSG4326,scale:function(a){return 256*(1<<a)},center:null,zoom:null,layers:[],dragging:!0,touchZoom:L.Browser.mobileWebkit&&!L.Browser.android,scrollWheelZoom:!L.Browser.mobileWebkit,doubleClickZoom:!0,shiftDragZoom:!0,zoomControl:!0,attributionControl:!0,fadeAnimation:L.DomUtil.TRANSITION&&!L.Browser.android,zoomAnimation:L.DomUtil.TRANSITION&&!L.Browser.android&&!L.Browser.mobileOpera,trackResize:!0,closePopupOnClick:!0},
-initialize:function(a,b){L.Util.setOptions(this,b);this._container=L.DomUtil.get(a);this._initLayout();L.DomEvent&&(this._initEvents(),L.Handler&&this._initInteraction(),L.Control&&this._initControls());var c=this.options.center,d=this.options.zoom;c!==null&&d!==null&&this.setView(c,d,!0);c=this.options.layers;c=c instanceof Array?c:[c];this._tileLayersNum=0;this._initLayers(c)},setView:function(a,b){this._resetView(a,this._limitZoom(b));return this},setZoom:function(a){return this.setView(this.getCenter(),
-a)},zoomIn:function(){return this.setZoom(this._zoom+1)},zoomOut:function(){return this.setZoom(this._zoom-1)},fitBounds:function(a){var b=this.getBoundsZoom(a);return this.setView(a.getCenter(),b)},fitWorld:function(){var a=new L.LatLng(-60,-170),b=new L.LatLng(85,179);return this.fitBounds(new L.LatLngBounds(a,b))},panTo:function(a){return this.setView(a,this._zoom)},panBy:function(a){this.fire("movestart");this._rawPanBy(a);this.fire("move");this.fire("moveend");return this},addLayer:function(a){var b=
-L.Util.stamp(a);if(this._layers[b])return this;this._layers[b]=a;if(a.options&&!isNaN(a.options.maxZoom))this._layersMaxZoom=Math.max(this._layersMaxZoom||0,a.options.maxZoom);if(a.options&&!isNaN(a.options.minZoom))this._layersMinZoom=Math.min(this._layersMinZoom||Infinity,a.options.minZoom);this.options.zoomAnimation&&L.TileLayer&&a instanceof L.TileLayer&&(this._tileLayersNum++,a.on("load",this._onTileLayerLoad,this));this.attributionControl&&a.getAttribution&&this.attributionControl.addAttribution(a.getAttribution());
-b=function(){a.onAdd(this);this.fire("layeradd",{layer:a})};if(this._loaded)b.call(this);else this.on("load",b,this);return this},removeLayer:function(a){var b=L.Util.stamp(a);this._layers[b]&&(a.onRemove(this),delete this._layers[b],this.options.zoomAnimation&&L.TileLayer&&a instanceof L.TileLayer&&(this._tileLayersNum--,a.off("load",this._onTileLayerLoad,this)),this.attributionControl&&a.getAttribution&&this.attributionControl.removeAttribution(a.getAttribution()),this.fire("layerremove",{layer:a}));
-return this},invalidateSize:function(){this._sizeChanged=!0;this.fire("move");clearTimeout(this._sizeTimer);this._sizeTimer=setTimeout(L.Util.bind(function(){this.fire("moveend")},this),200);return this},getCenter:function(a){var b=this.getSize().divideBy(2);return this.unproject(this._getTopLeftPoint().add(b),this._zoom,a)},getZoom:function(){return this._zoom},getBounds:function(){var a=this.getPixelBounds(),b=this.unproject(new L.Point(a.min.x,a.max.y)),a=this.unproject(new L.Point(a.max.x,a.min.y));
-return new L.LatLngBounds(b,a)},getMinZoom:function(){return isNaN(this.options.minZoom)?this._layersMinZoom||0:this.options.minZoom},getMaxZoom:function(){return isNaN(this.options.maxZoom)?this._layersMaxZoom||Infinity:this.options.maxZoom},getBoundsZoom:function(a){var b=this.getSize(),c=this.getMinZoom(),d=this.getMaxZoom(),e=a.getNorthEast(),a=a.getSouthWest(),f,g;do c++,f=this.project(e,c),g=this.project(a,c),f=new L.Point(f.x-g.x,g.y-f.y);while(f.x<=b.x&&f.y<=b.y&&c<=d);return c-1},getSize:function(){if(!this._size||
-this._sizeChanged)this._size=new L.Point(this._container.clientWidth,this._container.clientHeight),this._sizeChanged=!1;return this._size},getPixelBounds:function(){var a=this._getTopLeftPoint(),b=this.getSize();return new L.Bounds(a,a.add(b))},getPixelOrigin:function(){return this._initialTopLeftPoint},getPanes:function(){return this._panes},mouseEventToContainerPoint:function(a){return L.DomEvent.getMousePosition(a,this._container)},mouseEventToLayerPoint:function(a){return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(a))},
-mouseEventToLatLng:function(a){return this.layerPointToLatLng(this.mouseEventToLayerPoint(a))},containerPointToLayerPoint:function(a){return a.subtract(L.DomUtil.getPosition(this._mapPane))},layerPointToContainerPoint:function(a){return a.add(L.DomUtil.getPosition(this._mapPane))},layerPointToLatLng:function(a){return this.unproject(a.add(this._initialTopLeftPoint))},latLngToLayerPoint:function(a){return this.project(a)._subtract(this._initialTopLeftPoint)},project:function(a,b){b=typeof b=="undefined"?
-this._zoom:b;return this.options.crs.latLngToPoint(a,this.options.scale(b))},unproject:function(a,b,c){b=typeof b=="undefined"?this._zoom:b;return this.options.crs.pointToLatLng(a,this.options.scale(b),c)},_initLayout:function(){var a=this._container;a.className+=" leaflet-container";this.options.fadeAnimation&&(a.className+=" leaflet-fade-anim");var b=L.DomUtil.getStyle(a,"position");if(b!="absolute"&&b!="relative")a.style.position="relative";this._initPanes();this._initControlPos&&this._initControlPos()},
-_initPanes:function(){var a=this._panes={};this._mapPane=a.mapPane=this._createPane("leaflet-map-pane",this._container);this._tilePane=a.tilePane=this._createPane("leaflet-tile-pane",this._mapPane);this._objectsPane=a.objectsPane=this._createPane("leaflet-objects-pane",this._mapPane);a.shadowPane=this._createPane("leaflet-shadow-pane");a.overlayPane=this._createPane("leaflet-overlay-pane");a.markerPane=this._createPane("leaflet-marker-pane");a.popupPane=this._createPane("leaflet-popup-pane")},_createPane:function(a,
-b){return L.DomUtil.create("div",a,b||this._objectsPane)},_resetView:function(a,b,c){var d=this._zoom!=b;this.fire("movestart");this._zoom=b;this._initialTopLeftPoint=this._getNewTopLeftPoint(a);c?this._initialTopLeftPoint._add(L.DomUtil.getPosition(this._mapPane)):L.DomUtil.setPosition(this._mapPane,new L.Point(0,0));this._tileLayersToLoad=this._tileLayersNum;this.fire("viewreset");this.fire("move");d&&this.fire("zoomend");this.fire("moveend");if(!this._loaded)this._loaded=!0,this.fire("load")},
-_initLayers:function(a){this._layers={};for(var b=0,c=a.length;b<c;b++)this.addLayer(a[b])},_initControls:function(){this.options.zoomControl&&this.addControl(new L.Control.Zoom);if(this.options.attributionControl)this.attributionControl=new L.Control.Attribution,this.addControl(this.attributionControl)},_rawPanBy:function(a){var b=L.DomUtil.getPosition(this._mapPane);L.DomUtil.setPosition(this._mapPane,b.subtract(a))},_initEvents:function(){L.DomEvent.addListener(this._container,"click",this._onMouseClick,
-this);for(var a=["dblclick","mousedown","mouseenter","mouseleave","mousemove"],b=0;b<a.length;b++)L.DomEvent.addListener(this._container,a[b],this._fireMouseEvent,this);this.options.trackResize&&L.DomEvent.addListener(window,"resize",this.invalidateSize,this)},_onMouseClick:function(a){if(!this.dragging||!this.dragging.moved())this.fire("pre"+a.type),this._fireMouseEvent(a)},_fireMouseEvent:function(a){var b=a.type,b=b=="mouseenter"?"mouseover":b=="mouseleave"?"mouseout":b;this.hasEventListeners(b)&&
-this.fire(b,{latlng:this.mouseEventToLatLng(a),layerPoint:this.mouseEventToLayerPoint(a)})},_initInteraction:function(){var a={dragging:L.Handler.MapDrag,touchZoom:L.Handler.TouchZoom,doubleClickZoom:L.Handler.DoubleClickZoom,scrollWheelZoom:L.Handler.ScrollWheelZoom,shiftDragZoom:L.Handler.ShiftDragZoom},b;for(b in a)a.hasOwnProperty(b)&&a[b]&&(this[b]=new a[b](this),this.options[b]&&this[b].enable())},_onTileLayerLoad:function(){this._tileLayersToLoad--;if(this._tileLayersNum&&!this._tileLayersToLoad&&
-this._tileBg)clearTimeout(this._clearTileBgTimer),this._clearTileBgTimer=setTimeout(L.Util.bind(this._clearTileBg,this),500)},_getTopLeftPoint:function(){if(!this._loaded)throw Error("Set map center and zoom first.");return this._initialTopLeftPoint.subtract(L.DomUtil.getPosition(this._mapPane))},_getNewTopLeftPoint:function(a){var b=this.getSize().divideBy(2);return this.project(a).subtract(b).round()},_limitZoom:function(a){var b=this.getMinZoom(),c=this.getMaxZoom();return Math.max(b,Math.min(c,
-a))}});L.Map.include({locate:function(a){var b={timeout:1E4};L.Util.extend(b,a);navigator.geolocation?navigator.geolocation.getCurrentPosition(L.Util.bind(this._handleGeolocationResponse,this),L.Util.bind(this._handleGeolocationError,this),b):this.fire("locationerror",{code:0,message:"Geolocation not supported."});return this},locateAndSetView:function(a,b){this._setViewOnLocate=!0;this._maxLocateZoom=a||Infinity;return this.locate(b)},_handleGeolocationError:function(a){var a=a.code,b=a==1?"permission denied":
-a==2?"position unavailable":"timeout";if(this._setViewOnLocate)this.fitWorld(),this._setViewOnLocate=!1;this.fire("locationerror",{code:a,message:"Geolocation error: "+b+"."})},_handleGeolocationResponse:function(a){var b=180*a.coords.accuracy/4E7,c=b*2,d=a.coords.latitude,e=a.coords.longitude,f=new L.LatLng(d-b,e-c),b=new L.LatLng(d+b,e+c),f=new L.LatLngBounds(f,b);if(this._setViewOnLocate)b=Math.min(this.getBoundsZoom(f),this._maxLocateZoom),this.setView(f.getCenter(),b),this._setViewOnLocate=!1;
-this.fire("locationfound",{latlng:new L.LatLng(d,e),bounds:f,accuracy:a.coords.accuracy})}});L.Map.include({openPopup:function(a){this.closePopup();this._popup=a;return this.addLayer(a)},closePopup:function(){this._popup&&this.removeLayer(this._popup);return this}});L.Map.include(!L.Transition||!L.Transition.implemented()?{}:{setView:function(a,b,c){var b=this._limitZoom(b),d=this._zoom!=b;if(this._loaded&&!c&&this._layers&&(c=this._getNewTopLeftPoint(a).subtract(this._getTopLeftPoint()),d?this._zoomToIfCenterInView&&this._zoomToIfCenterInView(a,b,c):this._panByIfClose(c)))return this;this._resetView(a,b);return this},panBy:function(a){if(!this._panTransition)this._panTransition=new L.Transition(this._mapPane,{duration:0.3}),this._panTransition.on("step",this._onPanTransitionStep,
-this),this._panTransition.on("end",this._onPanTransitionEnd,this);this.fire(this,"movestart");this._panTransition.run({position:L.DomUtil.getPosition(this._mapPane).subtract(a)});return this},_onPanTransitionStep:function(){this.fire("move")},_onPanTransitionEnd:function(){this.fire("moveend")},_panByIfClose:function(a){if(this._offsetIsWithinView(a))return this.panBy(a),!0;return!1},_offsetIsWithinView:function(a,b){var c=b||1,d=this.getSize();return Math.abs(a.x)<=d.x*c&&Math.abs(a.y)<=d.y*c}});L.Map.include(!L.DomUtil.TRANSITION?{}:{_zoomToIfCenterInView:function(a,b,c){if(this._animatingZoom)return!0;if(!this.options.zoomAnimation)return!1;var d=Math.pow(2,b-this._zoom),c=c.divideBy(1-1/d);if(!this._offsetIsWithinView(c,1))return!1;this._mapPane.className+=" leaflet-zoom-anim";c=this.containerPointToLayerPoint(this.getSize().divideBy(2)).add(c);this._prepareTileBg();this._runAnimation(a,b,d,c);return!0},_runAnimation:function(a,b,c,d){this._animatingZoom=!0;this._animateToCenter=a;this._animateToZoom=
-b;a=L.DomUtil.TRANSFORM;if(L.Browser.gecko||window.opera)this._tileBg.style[a]+=" translate(0,0)";L.Browser.android?(this._tileBg.style[a+"Origin"]=d.x+"px "+d.y+"px",c="scale("+c+")"):c=L.DomUtil.getScaleString(c,d);L.Util.falseFn(this._tileBg.offsetWidth);d={};d[a]=this._tileBg.style[a]+" "+c;this._tileBg.transition.run(d)},_prepareTileBg:function(){if(!this._tileBg)this._tileBg=this._createPane("leaflet-tile-pane",this._mapPane),this._tileBg.style.zIndex=1;var a=this._tilePane,b=this._tileBg;b.style[L.DomUtil.TRANSFORM]=
-"";b.style.visibility="hidden";b.empty=!0;a.empty=!1;this._tilePane=this._panes.tilePane=b;this._tileBg=a;if(!this._tileBg.transition)this._tileBg.transition=new L.Transition(this._tileBg,{duration:0.3,easing:"cubic-bezier(0.25,0.1,0.25,0.75)"}),this._tileBg.transition.on("end",this._onZoomTransitionEnd,this);this._stopLoadingBgTiles()},_stopLoadingBgTiles:function(){for(var a=[].slice.call(this._tileBg.getElementsByTagName("img")),b=0,c=a.length;b<c;b++)if(!a[b].complete)a[b].src="",a[b].parentNode.removeChild(a[b])},
-_onZoomTransitionEnd:function(){this._restoreTileFront();L.Util.falseFn(this._tileBg.offsetWidth);this._resetView(this._animateToCenter,this._animateToZoom,!0);this._mapPane.className=this._mapPane.className.replace(" leaflet-zoom-anim","");this._animatingZoom=!1},_restoreTileFront:function(){this._tilePane.innerHTML="";this._tilePane.style.visibility="";this._tilePane.style.zIndex=2;this._tileBg.style.zIndex=1},_clearTileBg:function(){if(!this._animatingZoom&&!this.touchZoom._zooming)this._tileBg.innerHTML=
-""}});L.Map.include({addControl:function(a){a.onAdd(this);var b=a.getPosition(),c=this._controlCorners[b],a=a.getContainer();L.DomUtil.addClass(a,"leaflet-control");b.indexOf("bottom")!=-1?c.insertBefore(a,c.firstChild):c.appendChild(a);return this},removeControl:function(a){var b=this._controlCorners[a.getPosition()],c=a.getContainer();b.removeChild(c);if(a.onRemove)a.onRemove(this);return this},_initControlPos:function(){var a=this._controlCorners={},b=L.DomUtil.create("div","leaflet-control-container",
-this._container);L.Browser.mobileWebkit&&(b.className+=" leaflet-big-buttons");a.topLeft=L.DomUtil.create("div","leaflet-top leaflet-left",b);a.topRight=L.DomUtil.create("div","leaflet-top leaflet-right",b);a.bottomLeft=L.DomUtil.create("div","leaflet-bottom leaflet-left",b);a.bottomRight=L.DomUtil.create("div","leaflet-bottom leaflet-right",b)}});



https://bitbucket.org/yt_analysis/yt/changeset/d64640460807/
changeset:   d64640460807
branch:      yt
user:        MatthewTurk
date:        2012-06-24 05:06:34
summary:     Updating the help page.
affected #:  1 file

diff -r 054f19f0fe563c6c99b345b1c1f9e271d085f7b0 -r d646404608079c72a5f2354e097ea8840196db78 yt/gui/reason/html/help.html
--- a/yt/gui/reason/html/help.html
+++ b/yt/gui/reason/html/help.html
@@ -62,7 +62,7 @@
 }
 
 a {
-    /*text-decoration: none;*/
+    text-decoration: none;
 }
 
 a:link {
@@ -84,17 +84,15 @@
 </style><body><div class="yt_logo">
-<h1>yt:</h1>
-<p>because your data isn't going to analyze itself!</p>
+<h1>yt</h1><ul class="quick_list">
+<li><a href="http://yt-project.org/">home</a></li><li><a href="http://yt-project.org/doc/">docs</a></li>
-<li><a href="http://yt-project.org/wiki/Gallery">gallery</a> ( <a href="video_gallery.html">video</a> )</li>
-<li><a href="http://yt-project.org/wiki">wiki</a></li>
-<li><a href="http://yt-project.org/doc/orientation.html">quick start</a></li>
-<li><a href="http://yt-project.org/newticket">report a bug</a></li>
-<li><a href="http://yt-project.org/browser">source</a></li>
-<li><a href="principles.html">principles</a></li>
-<li><a href="http://blog.enzotools.org/">development blog</a></li>
+<li><a href="https://bitbucket.org/yt_analyis/yt/">development page</a></li>
+<li><a href="https://bitbucket.org/yt_analyis/yt/newticket">report a bug</a></li>
+<li><a href="http://yt-project.org/irc.html">chat</a></li>
+<li> </li>
+<li><a href="http://yt-project.org/docs/2.3/interacting/reason.html">reason manual</a></li></ul></div><div class="faq">
@@ -117,28 +115,22 @@
 images will be returned in the window.  You can click on these images to view
 them at full-size.</p>
 
-<h2>Using the interactive plot window</h2>
-<p>As you execute cells and load parameter files from disk, these parameter
-files will get added to the tree view on the left, along with any objects that
-have been created from them.</p>
+<h2>Interactive Visualization</h2>
+<p>Once you have loaded data off disk, either by loading it in the Notebook,
+or choosing "Load File" from the menu, you can right click on any object
+in the left hand menu to choose different visualization options.</p>
 
-<p>Over time, these objects will expose right-click events to create plot
-windows, as well as drag-and-drop functionality.</p>
+<p>You can also supply files on the command line when starting Reason, or run
+with "-f" to search for them in the current directory.</p>
 
-<h2>Saving and loading sessions</h2>
-<p>There are three methods for saving your work.  You can click "Download" to
-download a copy of your session on your local machine.  By clicking "Save" you
-can save a copy on the server on which Reason is running.  By clicking
-"Pastebin" you can send a copy of it to the <a
-href="http://paste.yt-project.org/">yt pastebin</a>.</p>
-
-<p>If you use the command 'load_script' and supply it a file the server can
-find locally, it will read that file in and populate the contents of your next
-submission cell with it.</p>
+<h2>Delivering Images and Scripts</h2>
+<p>The command <tt>deliver_image('filename.png')</tt> will display the file
+<tt>filename.png</tt> in the output window.  The command <tt>load_script('filename.py')</tt>
+will fill the execution area with the script <tt>filename.py</tt>.</p><h2>How to Quit</h2>
-<p>To quit, simply press Ctrl-C in the console window that you ran "yt serve"
-within.</p>
+<p>To quit, either choose "Quit" from the menu or press Ctrl-C in the console
+window that you ran "yt serve" within.</p></div></body>



https://bitbucket.org/yt_analysis/yt/changeset/610232d16886/
changeset:   610232d16886
branch:      yt
user:        brittonsmith
date:        2012-06-24 05:33:33
summary:     Made some changes to get intermediate payloads, not quite there yet.
affected #:  4 files

diff -r d646404608079c72a5f2354e097ea8840196db78 -r 610232d168862aeb955e2f8b7bc5402955b39b33 scripts/pyro_queue.py
--- a/scripts/pyro_queue.py
+++ b/scripts/pyro_queue.py
@@ -13,6 +13,7 @@
 my_rank = comm.comm.rank
 
 if my_rank == 0:
+    from yt.config import ytcfg;ytcfg["yt","__withinreason"]="True"
     my_q = PyroQueueRoot(comm)
     Pyro4.config.HMAC_KEY = uuid.uuid4().hex
     key_file = 'reason.key'


diff -r d646404608079c72a5f2354e097ea8840196db78 -r 610232d168862aeb955e2f8b7bc5402955b39b33 yt/gui/reason/basic_repl.py
--- a/yt/gui/reason/basic_repl.py
+++ b/yt/gui/reason/basic_repl.py
@@ -34,8 +34,10 @@
 from cStringIO import StringIO
 
 class ProgrammaticREPL(object):
-    
+    stopped = False
+    debug = False
     def __init__(self, locals=None):
+        self.executed_cell_texts = []
         self.locals = {}
         if locals:
             self.locals.update(locals)


diff -r d646404608079c72a5f2354e097ea8840196db78 -r 610232d168862aeb955e2f8b7bc5402955b39b33 yt/gui/reason/extdirect_repl.py
--- a/yt/gui/reason/extdirect_repl.py
+++ b/yt/gui/reason/extdirect_repl.py
@@ -79,6 +79,7 @@
 class ExecutionThread(threading.Thread):
     def __init__(self, repl):
         self.repl = repl
+        self.payload_handler = PayloadHandler()
         self.queue = Queue.Queue()
         threading.Thread.__init__(self)
         self.daemon = True
@@ -117,7 +118,7 @@
             print result
             print "========================================================"
         if not hide:
-            self.repl.payload_handler.add_payload(
+            self.payload_handler.add_payload(
                 {'type': 'cell',
                  'output': result,
                  'input': highlighter(code),
@@ -125,7 +126,7 @@
                  'raw_input': code},
                 )
         objs = get_list_of_datasets()
-        self.repl.payload_handler.add_payload(
+        self.payload_handler.add_payload(
             {'type': 'dataobjects',
              'objs': objs})
 
@@ -219,8 +220,6 @@
     my_name = "ExtDirectREPL"
     timeout = 660 # a minute longer than the rocket server timeout
     server = None
-    stopped = False
-    debug = False
     _heartbeat_timer = None
 
     def __init__(self, reasonjs_path, locals=None,
@@ -246,7 +245,6 @@
         # This has to be routed to the root directory
         self.api_url = "repl"
         BottleDirectRouter.__init__(self)
-        self.executed_cell_texts = []
         self.payload_handler = PayloadHandler()
         if use_pyro:
             self.execution_thread = PyroExecutionThread(self)


diff -r d646404608079c72a5f2354e097ea8840196db78 -r 610232d168862aeb955e2f8b7bc5402955b39b33 yt/gui/reason/pyro_queue.py
--- a/yt/gui/reason/pyro_queue.py
+++ b/yt/gui/reason/pyro_queue.py
@@ -30,6 +30,7 @@
 from yt.funcs import *
 
 from yt.gui.reason.basic_repl import ProgrammaticREPL
+from yt.gui.reason.extdirect_repl import ExecutionThread
 from yt.gui.reason.bottle_mods import PayloadHandler
 from .utils import get_list_of_datasets
 
@@ -37,16 +38,14 @@
     def __init__(self, comm):
         self.comm = comm
         self.repl = ProgrammaticREPL()
+        self.execution_thread = ExecutionThread(self.repl)
         self.payload_handler = PayloadHandler()
+        self.execution_thread.start()
 
     def execute(self, code):
         mylog.info('Root sending out code.')
         code = self.comm.comm.bcast(code, root=0)
-        value = self.repl.execute(code)
-        datasets = get_list_of_datasets()
-        self.payload_handler.add_payload({'type': 'dataobjects',
-                                          'objs': datasets})
-        return value
+        self.execution_thread.execute_one(code, False)
 
     def deliver(self):
         return self.payload_handler.deliver_payloads()



https://bitbucket.org/yt_analysis/yt/changeset/c3a106c2c670/
changeset:   c3a106c2c670
branch:      yt
user:        MatthewTurk
date:        2012-06-24 05:52:09
summary:     Progressbars and log entries should now get sent back from the root of the
task queue.
affected #:  4 files

diff -r 610232d168862aeb955e2f8b7bc5402955b39b33 -r c3a106c2c6704a9a6f3a055fa233b60b7955ee9a scripts/pyro_queue.py
--- a/scripts/pyro_queue.py
+++ b/scripts/pyro_queue.py
@@ -1,3 +1,4 @@
+from yt.config import ytcfg;ytcfg["yt","__withinreason"]="True"
 import os
 import Pyro4
 import uuid
@@ -13,7 +14,6 @@
 my_rank = comm.comm.rank
 
 if my_rank == 0:
-    from yt.config import ytcfg;ytcfg["yt","__withinreason"]="True"
     my_q = PyroQueueRoot(comm)
     Pyro4.config.HMAC_KEY = uuid.uuid4().hex
     key_file = 'reason.key'


diff -r 610232d168862aeb955e2f8b7bc5402955b39b33 -r c3a106c2c6704a9a6f3a055fa233b60b7955ee9a yt/funcs.py
--- a/yt/funcs.py
+++ b/yt/funcs.py
@@ -310,19 +310,11 @@
     from yt.config import ytcfg
     if ytcfg.getboolean("yt","suppressStreamLogging"):
         return DummyProgressBar()
-    elif ytcfg.getboolean("yt", "__parallel"):
-        return ParallelProgressBar(title, maxval)
-    elif "SAGE_ROOT" in os.environ:
-        try:
-            from sage.server.support import EMBEDDED_MODE
-            if EMBEDDED_MODE: return DummyProgressBar()
-        except:
-            pass
-    elif "CODENODE" in os.environ:
-        return DummyProgressBar()
     elif ytcfg.getboolean("yt", "__withinreason"):
         from yt.gui.reason.extdirect_repl import ExtProgressBar
         return ExtProgressBar(title, maxval)
+    elif ytcfg.getboolean("yt", "__parallel"):
+        return ParallelProgressBar(title, maxval)
     widgets = [ title,
             pb.Percentage(), ' ',
             pb.Bar(marker=pb.RotatingMarker()),


diff -r 610232d168862aeb955e2f8b7bc5402955b39b33 -r c3a106c2c6704a9a6f3a055fa233b60b7955ee9a yt/gui/reason/extdirect_repl.py
--- a/yt/gui/reason/extdirect_repl.py
+++ b/yt/gui/reason/extdirect_repl.py
@@ -84,6 +84,9 @@
         threading.Thread.__init__(self)
         self.daemon = True
 
+    def heartbeat(self):
+        return
+
     def run(self):
         while 1:
             #print "Checking for a queue ..."
@@ -92,7 +95,7 @@
             except Queue.Empty:
                 if self.repl.stopped: return
                 continue
-            #print "Received the task", task
+            print "Received the task", task
             if task['type'] == 'code':
                 self.execute_one(task['code'], task['hide'])
                 self.queue.task_done()
@@ -154,20 +157,9 @@
             self.repl.payload_handler.add_payload(p)
 
     def heartbeat(self):
-        self.last_heartbeat = time.time()
-        if self.debug: print "### Heartbeat ... started: %s" % (time.ctime())
-        for i in range(30):
-            # Check for stop
-            if self.debug: print "    ###"
-            if self.stopped: return {'type':'shutdown'} # No race condition
-            if self.payload_handler.event.wait(1): # One second timeout
-                if self.debug: print "    ### Delivering payloads"
-                rv = self.payload_handler.deliver_payloads()
-                if self.debug: print "    ### Got back, returning"
-                return rv
-        if self.debug: print "### Heartbeat ... finished: %s" % (time.ctime())
-        return []
-
+        ph = self.executor.deliver()
+        for p in ph:
+            self.repl.payload_handler.add_payload(p)
 
 def reason_pylab():
     from .utils import deliver_image
@@ -294,6 +286,7 @@
                 rv = self.payload_handler.deliver_payloads()
                 if self.debug: print "    ### Got back, returning"
                 return rv
+            self.execution_thread.heartbeat()
         if self.debug: print "### Heartbeat ... finished: %s" % (time.ctime())
         return []
 
@@ -352,11 +345,11 @@
         return highlighter_css
 
     def execute(self, code, hide = False):
-            task = {'type': 'code',
-                    'code': code,
-                    'hide': hide}
-            self.execution_thread.queue.put(task)
-            return dict(status = True)
+        task = {'type': 'code',
+                'code': code,
+                'hide': hide}
+        self.execution_thread.queue.put(task)
+        return dict(status = True)
 
     def get_history(self):
         return self.executed_cell_texts[:]


diff -r 610232d168862aeb955e2f8b7bc5402955b39b33 -r c3a106c2c6704a9a6f3a055fa233b60b7955ee9a yt/gui/reason/pyro_queue.py
--- a/yt/gui/reason/pyro_queue.py
+++ b/yt/gui/reason/pyro_queue.py
@@ -42,10 +42,13 @@
         self.payload_handler = PayloadHandler()
         self.execution_thread.start()
 
-    def execute(self, code):
+    def execute(self, code, hide = False):
         mylog.info('Root sending out code.')
         code = self.comm.comm.bcast(code, root=0)
-        self.execution_thread.execute_one(code, False)
+        task = {'type': 'code',
+                'code': code,
+                'hide': hide}
+        self.execution_thread.queue.put(task)
 
     def deliver(self):
         return self.payload_handler.deliver_payloads()



https://bitbucket.org/yt_analysis/yt/changeset/03793d594be9/
changeset:   03793d594be9
branch:      yt
user:        MatthewTurk
date:        2012-06-24 06:10:52
summary:     Fixed the field listing in the plot window creation dialog.
affected #:  2 files

diff -r c3a106c2c6704a9a6f3a055fa233b60b7955ee9a -r 03793d594be982f6c1658351f5e4a667eb881f83 yt/gui/reason/html/app/controller/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
@@ -252,9 +252,13 @@
             }
             var title = widget.templateManager.applyObject(obj, 'pwt');
             win = Ext.widget("plotwindowcreator", {title:title, obj:obj});
-            win.query("#weightField")[0].store = 
-                ['None'].concat(obj.field_list);
-            win.query("#field")[0].store = obj.field_list;
+            console.log(obj.field_list);
+            var field_list = [];
+            Ext.each(obj.field_list, function(f, i, af) {
+                field_list.push(f.text);
+            });
+            win.query("#weightField")[0].store = ['None'].concat(field_list);
+            win.query("#field")[0].store = field_list;
             win.query("#create")[0].on('click', makePlot);
             win.query("#cancel")[0].on('click', function(){win.destroy();});
             win.query("#maxDens")[0].on('change', toggleMaxDens);


diff -r c3a106c2c6704a9a6f3a055fa233b60b7955ee9a -r 03793d594be982f6c1658351f5e4a667eb881f83 yt/gui/reason/html/app/view/widgets/PlotWindowCreator.js
--- a/yt/gui/reason/html/app/view/widgets/PlotWindowCreator.js
+++ b/yt/gui/reason/html/app/view/widgets/PlotWindowCreator.js
@@ -88,6 +88,8 @@
                   fieldLabel: 'Field',
                   itemId: 'field',
                   store: [],
+                  displayField: 'text',
+                  valueield: 'text',
                   width: 200,
                   allowBlank:false,
                   triggerAction: 'all',
@@ -103,7 +105,9 @@
                   xtype:'combo',
                   fieldLabel: 'Weight Field',
                   itemId: 'weightField',
-                  store: ['None'],
+                  store: [{text:'None'},],
+                  displayField: 'text',
+                  valueield: 'text',
                   width: 200,
                   allowBlank:false,
                   triggerAction: 'all',



https://bitbucket.org/yt_analysis/yt/changeset/71ceede82775/
changeset:   71ceede82775
branch:      yt
user:        ngoldbaum
date:        2012-06-24 07:27:29
summary:     An attempt at getting the keyframes right.  Still doesn't work.
affected #:  1 file

diff -r 8fa22fea15f1c63744889b8f837ea5addef04cac -r 71ceede82775407793c71670ae2a5f063ff68aa4 yt/gui/reason/widget_store.py
--- a/yt/gui/reason/widget_store.py
+++ b/yt/gui/reason/widget_store.py
@@ -259,22 +259,30 @@
     def render_path(self, views, times, N):
         # Assume that path comes in as a list of matrice
         # Assume original vector is (0., 0., 1.), up is (0., 1., 0.)
-        # for matrix in matrices:
+        
+        views = [na.array(view).transpose() for view in views]
 
-        views = [na.array(view) for view in views]
-        
         times = na.linspace(0.0,1.0,len(times))
-        norm = na.array([0.,0.,1.,1.])
-        up = na.array([0.,1.,0.,1.])
-        
-        centers = na.array([na.dot(na.eye(4)*R[3,2],na.dot(R, norm)) for R in views])
-        r = views[0]
-        print r 
-        ups = na.array([na.dot(R,up) for R in views])
-        print 'centers'
-        for center in centers: print center
-        print 'ups'
-        for up in ups: print up
+                
+        # This is wrong.
+        reflect = na.array([[1,0,0],[0,1,0],[0,0,-1]])
+
+        rots = na.array([R[0:3,0:3] for R in views])
+
+        rots = na.array([na.dot(reflect,rot) for rot in rots])
+
+        centers = na.array([na.dot(rot,R[0:3,3]) for R,rot in zip(views,rots)])
+
+        ups = na.array([na.dot(rot,R[0:3,1]) for R,rot in zip(views,rots)])
+
+        #print 'views'
+        #for view in views: print view
+        #print 'rots'
+        #for rot in rots: print rot
+        #print 'centers'
+        #for center in centers: print center
+        #print 'ups'
+        #for up in ups: print up
 
         pos = na.empty((N,3), dtype="float64")
         uv = na.empty((N,3), dtype="float64")



https://bitbucket.org/yt_analysis/yt/changeset/fdc44a69a481/
changeset:   fdc44a69a481
branch:      yt
user:        ngoldbaum
date:        2012-06-24 07:28:14
summary:     Merging
affected #:  28 files

diff -r 71ceede82775407793c71670ae2a5f063ff68aa4 -r fdc44a69a4814a753dd1b7e9a738a8f1c99bba33 doc/install_script.sh
--- a/doc/install_script.sh
+++ b/doc/install_script.sh
@@ -332,7 +332,7 @@
     sleep 60
 fi
 
-function get_enzotools
+function get_ytproject
 {
     echo "Downloading $1 from yt-project.org"
     [ -e $1 ] && return
@@ -358,7 +358,7 @@
 echo '44eea803870a66ff0bab08d13a8b3388b5578ebc1c807d1d9dca0a93e6371e91b15d02917a00b3b20dc67abb5a21dabaf9b6e9257a561f85eeff2147ac73b478  PyX-0.11.1.tar.gz' > PyX-0.11.1.tar.gz.sha512
 echo '1a754d560bfa433f0960ab3b5a62edb5f291be98ec48cf4e5941fa5b84139e200b87a52efbbd6fa4a76d6feeff12439eed3e7a84db4421940d1bbb576f7a684e  Python-2.7.2.tgz' > Python-2.7.2.tgz.sha512
 echo 'c017d3d59dd324ac91af0edc178c76b60a5f90fbb775cf843e39062f95bd846238f2c53705f8890ed3f34bc0e6e75671a73d13875eb0287d6201cb45f0a2d338  bzip2-1.0.5.tar.gz' > bzip2-1.0.5.tar.gz.sha512
-echo '445de41f63a03bf1c098e36b5658590d8837a80ecd3ce8ff6544d30653cc64ce2521e6354016ca3b56a35a8416c33567506db8acec29ea3d9d97ae5f2e7eca02  ext-4.1.0-gpl.zip' > ext-4.1.0-gpl.zip.sha512
+echo 'a296dfcaef7e853e58eed4e24b37c4fa29cfc6ac688def048480f4bb384b9e37ca447faf96eec7b378fd764ba291713f03ac464581d62275e28eb2ec99110ab6  reason-js-20120623.zip' > reason-js-20120623.zip.sha512
 echo 'b519218f93946400326e9b656669269ecb3e5232b944e18fbc3eadc4fe2b56244d68aae56d6f69042b4c87c58c881ee2aaa279561ea0f0f48d5842155f4de9de  freetype-2.4.4.tar.gz' > freetype-2.4.4.tar.gz.sha512
 echo '1531789e0a77d4829796d18552a4de7aecae7e8b63763a7951a8091921995800740fe03e72a7dbd496a5590828131c5f046ddead695e5cba79343b8c205148d1  h5py-2.0.1.tar.gz' > h5py-2.0.1.tar.gz.sha512
 echo '9644896e4a84665ad22f87eb885cbd4a0c60a5c30085d5dd5dba5f3c148dbee626f0cb01e59a7995a84245448a3f1e9ba98687d3f10250e2ee763074ed8ddc0e  hdf5-1.8.7.tar.gz' > hdf5-1.8.7.tar.gz.sha512
@@ -374,24 +374,24 @@
 echo '57fa5e57dfb98154a42d2d477f29401c2260ae7ad3a8128a4098b42ee3b35c54367b1a3254bc76b9b3b14b4aab7c3e1135858f68abc5636daedf2f01f9b8a3cf  tornado-2.2.tar.gz' > tornado-2.2.tar.gz.sha512
 
 # Individual processes
-[ -z "$HDF5_DIR" ] && get_enzotools hdf5-1.8.7.tar.gz
-[ $INST_ZLIB -eq 1 ] && get_enzotools zlib-1.2.3.tar.bz2 
-[ $INST_BZLIB -eq 1 ] && get_enzotools bzip2-1.0.5.tar.gz
-[ $INST_PNG -eq 1 ] && get_enzotools libpng-1.2.43.tar.gz
-[ $INST_FTYPE -eq 1 ] && get_enzotools freetype-2.4.4.tar.gz
-[ $INST_SQLITE3 -eq 1 ] && get_enzotools sqlite-autoconf-3070500.tar.gz
-[ $INST_PYX -eq 1 ] && get_enzotools PyX-0.11.1.tar.gz
-[ $INST_0MQ -eq 1 ] && get_enzotools zeromq-2.2.0.tar.gz
-[ $INST_0MQ -eq 1 ] && get_enzotools pyzmq-2.1.11.tar.gz
-[ $INST_0MQ -eq 1 ] && get_enzotools tornado-2.2.tar.gz
-get_enzotools Python-2.7.2.tgz
-get_enzotools numpy-1.6.1.tar.gz
-get_enzotools matplotlib-1.1.0.tar.gz
-get_enzotools mercurial-2.2.2.tar.gz
-get_enzotools ipython-0.12.tar.gz
-get_enzotools h5py-2.0.1.tar.gz
-get_enzotools Cython-0.16.tar.gz
-get_enzotools ext-4.1.0-gpl.zip
+[ -z "$HDF5_DIR" ] && get_ytproject hdf5-1.8.7.tar.gz
+[ $INST_ZLIB -eq 1 ] && get_ytproject zlib-1.2.3.tar.bz2 
+[ $INST_BZLIB -eq 1 ] && get_ytproject bzip2-1.0.5.tar.gz
+[ $INST_PNG -eq 1 ] && get_ytproject libpng-1.2.43.tar.gz
+[ $INST_FTYPE -eq 1 ] && get_ytproject freetype-2.4.4.tar.gz
+[ $INST_SQLITE3 -eq 1 ] && get_ytproject sqlite-autoconf-3070500.tar.gz
+[ $INST_PYX -eq 1 ] && get_ytproject PyX-0.11.1.tar.gz
+[ $INST_0MQ -eq 1 ] && get_ytproject zeromq-2.2.0.tar.gz
+[ $INST_0MQ -eq 1 ] && get_ytproject pyzmq-2.1.11.tar.gz
+[ $INST_0MQ -eq 1 ] && get_ytproject tornado-2.2.tar.gz
+get_ytproject Python-2.7.2.tgz
+get_ytproject numpy-1.6.1.tar.gz
+get_ytproject matplotlib-1.1.0.tar.gz
+get_ytproject mercurial-2.2.2.tar.gz
+get_ytproject ipython-0.12.tar.gz
+get_ytproject h5py-2.0.1.tar.gz
+get_ytproject Cython-0.16.tar.gz
+get_ytproject reason-js-20120623.zip
 
 if [ $INST_BZLIB -eq 1 ]
 then


diff -r 71ceede82775407793c71670ae2a5f063ff68aa4 -r fdc44a69a4814a753dd1b7e9a738a8f1c99bba33 scripts/pyro_queue.py
--- /dev/null
+++ b/scripts/pyro_queue.py
@@ -0,0 +1,31 @@
+from yt.config import ytcfg;ytcfg["yt","__withinreason"]="True"
+import os
+import Pyro4
+import uuid
+
+from yt.mods import *
+from yt.utilities.parallel_tools.parallel_analysis_interface import \
+    _get_comm
+from yt.gui.reason.pyro_queue import \
+    PyroQueueRoot, \
+    PyroQueueNonRoot
+
+comm = _get_comm(())
+my_rank = comm.comm.rank
+
+if my_rank == 0:
+    my_q = PyroQueueRoot(comm)
+    Pyro4.config.HMAC_KEY = uuid.uuid4().hex
+    key_file = 'reason.key'
+    fd = os.open(key_file, os.O_CREAT, 0600)
+    os.close(fd)
+    out_file = file(key_file, 'w')
+    out_file.write("HMAC KEY: %s\n" % Pyro4.config.HMAC_KEY)
+    out_file.close()
+    mylog.info('See %s for HMAC key.', key_file)
+    Pyro4.Daemon.serveSimple(
+        {my_q: "yt.executor"},
+        ns=False, verbose=True)
+else:
+    my_q = PyroQueueNonRoot(comm)
+    my_q.run()


diff -r 71ceede82775407793c71670ae2a5f063ff68aa4 -r fdc44a69a4814a753dd1b7e9a738a8f1c99bba33 yt/funcs.py
--- a/yt/funcs.py
+++ b/yt/funcs.py
@@ -310,19 +310,11 @@
     from yt.config import ytcfg
     if ytcfg.getboolean("yt","suppressStreamLogging"):
         return DummyProgressBar()
-    elif ytcfg.getboolean("yt", "__parallel"):
-        return ParallelProgressBar(title, maxval)
-    elif "SAGE_ROOT" in os.environ:
-        try:
-            from sage.server.support import EMBEDDED_MODE
-            if EMBEDDED_MODE: return DummyProgressBar()
-        except:
-            pass
-    elif "CODENODE" in os.environ:
-        return DummyProgressBar()
     elif ytcfg.getboolean("yt", "__withinreason"):
         from yt.gui.reason.extdirect_repl import ExtProgressBar
         return ExtProgressBar(title, maxval)
+    elif ytcfg.getboolean("yt", "__parallel"):
+        return ParallelProgressBar(title, maxval)
     widgets = [ title,
             pb.Percentage(), ' ',
             pb.Bar(marker=pb.RotatingMarker()),


diff -r 71ceede82775407793c71670ae2a5f063ff68aa4 -r fdc44a69a4814a753dd1b7e9a738a8f1c99bba33 yt/gui/reason/basic_repl.py
--- a/yt/gui/reason/basic_repl.py
+++ b/yt/gui/reason/basic_repl.py
@@ -34,8 +34,10 @@
 from cStringIO import StringIO
 
 class ProgrammaticREPL(object):
-    
+    stopped = False
+    debug = False
     def __init__(self, locals=None):
+        self.executed_cell_texts = []
         self.locals = {}
         if locals:
             self.locals.update(locals)


diff -r 71ceede82775407793c71670ae2a5f063ff68aa4 -r fdc44a69a4814a753dd1b7e9a738a8f1c99bba33 yt/gui/reason/extdirect_repl.py
--- a/yt/gui/reason/extdirect_repl.py
+++ b/yt/gui/reason/extdirect_repl.py
@@ -40,6 +40,7 @@
 import base64
 import imp
 import threading
+import Pyro4
 import Queue
 import zipfile
 
@@ -53,6 +54,7 @@
 from .bottle_mods import preroute, BottleDirectRouter, notify_route, \
                          PayloadHandler, lockit
 from yt.utilities.bottle import response, request, route, static_file
+from .utils import get_list_of_datasets
 from .basic_repl import ProgrammaticREPL
 
 try:
@@ -77,10 +79,14 @@
 class ExecutionThread(threading.Thread):
     def __init__(self, repl):
         self.repl = repl
+        self.payload_handler = PayloadHandler()
         self.queue = Queue.Queue()
         threading.Thread.__init__(self)
         self.daemon = True
 
+    def heartbeat(self):
+        return
+
     def run(self):
         while 1:
             #print "Checking for a queue ..."
@@ -89,7 +95,7 @@
             except Queue.Empty:
                 if self.repl.stopped: return
                 continue
-            #print "Received the task", task
+            print "Received the task", task
             if task['type'] == 'code':
                 self.execute_one(task['code'], task['hide'])
                 self.queue.task_done()
@@ -115,29 +121,48 @@
             print result
             print "========================================================"
         if not hide:
+            self.payload_handler.add_payload(
+                {'type': 'cell',
+                 'output': result,
+                 'input': highlighter(code),
+                 'image_data': '',
+                 'raw_input': code},
+                )
+        objs = get_list_of_datasets()
+        self.payload_handler.add_payload(
+            {'type': 'dataobjects',
+             'objs': objs})
+
+class PyroExecutionThread(ExecutionThread):
+    def __init__(self, repl):
+        ExecutionThread.__init__(self, repl)
+        hmac_key = raw_input("HMAC_KEY? ").strip()
+        uri = raw_input("URI? ").strip()
+        Pyro4.config.HMAC_KEY = hmac_key
+        self.executor = Pyro4.Proxy(uri)
+
+    def execute_one(self, code, hide):
+        self.repl.executed_cell_texts.append(code)
+        print code
+        result = self.executor.execute(code)
+        if not hide:
             self.repl.payload_handler.add_payload(
                 {'type': 'cell',
                  'output': result,
                  'input': highlighter(code),
                  'raw_input': code},
                 )
+        ph = self.executor.deliver()
+        for p in ph:
+            self.repl.payload_handler.add_payload(p)
 
-def deliver_image(im):
-    if hasattr(im, 'read'):
-        img_data = base64.b64encode(im.read())
-    elif isinstance(im, types.StringTypes) and \
-         im.endswith(".png"):
-        img_data = base64.b64encode(open(im).read())
-    elif isinstance(im, types.StringTypes):
-        img_data = im
-    else:
-        raise RuntimeError
-    ph = PayloadHandler()
-    payload = {'type':'png_string',
-               'image_data':img_data}
-    ph.add_payload(payload)
+    def heartbeat(self):
+        ph = self.executor.deliver()
+        for p in ph:
+            self.repl.payload_handler.add_payload(p)
 
 def reason_pylab():
+    from .utils import deliver_image
     def _canvas_deliver(canvas):
         tf = tempfile.TemporaryFile()
         canvas.print_png(tf)
@@ -170,19 +195,29 @@
     matplotlib.rcParams["backend"] = "module://reason_agg"
     pylab.switch_backend("module://reason_agg")
 
+_startup_template = r"""\
+import pylab
+from yt.mods import *
+from yt.gui.reason.utils import load_script, deliver_image
+from yt.gui.reason.widget_store import WidgetStore
+from yt.data_objects.static_output import _cached_pfs
+
+pylab.ion()
+data_objects = []
+widget_store = WidgetStore()
+"""
+
 class ExtDirectREPL(ProgrammaticREPL, BottleDirectRouter):
     _skip_expose = ('index')
     my_name = "ExtDirectREPL"
     timeout = 660 # a minute longer than the rocket server timeout
     server = None
-    stopped = False
-    debug = False
     _heartbeat_timer = None
 
-    def __init__(self, base_extjs_path, locals=None):
+    def __init__(self, reasonjs_path, locals=None,
+                 use_pyro=False):
         # First we do the standard initialization
-        self.extjs_file = zipfile.ZipFile(os.path.join(
-            base_extjs_path, "ext-4.1.0-gpl.zip"), 'r')
+        self.reasonjs_file = zipfile.ZipFile(reasonjs_path, 'r')
         ProgrammaticREPL.__init__(self, locals)
         # Now, since we want to only preroute functions we know about, and
         # since they have different arguments, and most of all because we only
@@ -194,7 +229,7 @@
                               _myapi = ("/ext-repl-api.js", "GET"),
                               _session_py = ("/session.py", "GET"),
                               _highlighter_css = ("/highlighter.css", "GET"),
-                              _extjs = ("/resources/extjs-4.1.0/:path#.+#", "GET"),
+                              _reasonjs = ("/reason-js/:path#.+#", "GET"),
                               _app = ("/reason/:path#.+#", "GET"),
                               )
         for v, args in preroute_table.items():
@@ -202,21 +237,17 @@
         # This has to be routed to the root directory
         self.api_url = "repl"
         BottleDirectRouter.__init__(self)
-        self.pflist = ExtDirectParameterFileList()
-        self.executed_cell_texts = []
         self.payload_handler = PayloadHandler()
-        self.execution_thread = ExecutionThread(self)
+        if use_pyro:
+            self.execution_thread = PyroExecutionThread(self)
+        else:
+            self.execution_thread = ExecutionThread(self)
         # We pass in a reference to ourself
+        self.execute(_startup_template)
         self.widget_store = WidgetStore(self)
         # Now we load up all the yt.mods stuff, but only after we've finished
         # setting up.
         reason_pylab()
-        self.execute("from yt.mods import *\nimport pylab\npylab.ion()")
-        self.execute("from yt.data_objects.static_output import _cached_pfs", hide = True)
-        self.execute("data_objects = []", hide = True)
-        self.locals['load_script'] = ext_load_script
-        self.locals['deliver_image'] = deliver_image
-        self.locals['widget_store'] = self.widget_store
 
     def activate(self):
         self.payload_handler._prefix = self._global_token
@@ -224,6 +255,7 @@
         # Setup our heartbeat
         self.last_heartbeat = time.time()
         self._check_heartbeat()
+        self.execute("widget_store._global_token = '%s'" % self._global_token)
         self.execution_thread.start()
 
     def exception_handler(self, exc):
@@ -254,6 +286,7 @@
                 rv = self.payload_handler.deliver_payloads()
                 if self.debug: print "    ### Got back, returning"
                 return rv
+            self.execution_thread.heartbeat()
         if self.debug: print "### Heartbeat ... finished: %s" % (time.ctime())
         return []
 
@@ -288,10 +321,10 @@
         root = os.path.join(local_dir, "html")
         return static_file("help.html", root)
 
-    def _extjs(self, path):
-        pp = os.path.join("extjs-4.1.0", path)
+    def _reasonjs(self, path):
+        pp = os.path.join("reason-js", path)
         try:
-            f = self.extjs_file.open(pp)
+            f = self.reasonjs_file.open(pp)
         except KeyError:
             response.status = 404
             return
@@ -312,11 +345,11 @@
         return highlighter_css
 
     def execute(self, code, hide = False):
-            task = {'type': 'code',
-                    'code': code,
-                    'hide': hide}
-            self.execution_thread.queue.put(task)
-            return dict(status = True)
+        task = {'type': 'code',
+                'code': code,
+                'hide': hide}
+        self.execution_thread.queue.put(task)
+        return dict(status = True)
 
     def get_history(self):
         return self.executed_cell_texts[:]
@@ -422,45 +455,6 @@
             results.append((os.path.basename(fn), size, t))
         return dict(objs = results, cur_dir=cur_dir)
 
-class ExtDirectParameterFileList(BottleDirectRouter):
-    my_name = "ExtDirectParameterFileList"
-    api_url = "pflist"
-
-    def get_list_of_pfs(self):
-        # Note that this instantiates the hierarchy.  This can be a costly
-        # event.  However, we're going to assume that it's okay, if you have
-        # decided to load up the parameter file.
-        from yt.data_objects.static_output import _cached_pfs
-        rv = []
-        for fn, pf in sorted(_cached_pfs.items()):
-            objs = []
-            pf_varname = "_cached_pfs['%s']" % (fn)
-            field_list = []
-            if pf._instantiated_hierarchy is not None: 
-                field_list = list(set(pf.h.field_list + pf.h.derived_field_list))
-                field_list = [dict(text = f) for f in sorted(field_list)]
-                for i,obj in enumerate(pf.h.objects):
-                    try:
-                        name = str(obj)
-                    except ReferenceError:
-                        continue
-                    objs.append(dict(name=name, type=obj._type_name,
-                                     filename = '', field_list = [],
-                                     varname = "%s.h.objects[%s]" % (pf_varname, i)))
-            rv.append( dict(name = str(pf), children = objs, filename=fn,
-                            type = "parameter_file",
-                            varname = pf_varname, field_list = field_list) )
-        return rv
-
-def ext_load_script(filename):
-    contents = open(filename).read()
-    payload_handler = PayloadHandler()
-    payload_handler.add_payload(
-        {'type': 'cell_contents',
-         'value': contents}
-    )
-    return
-
 class PayloadLoggingHandler(logging.StreamHandler):
     def __init__(self, *args, **kwargs):
         logging.StreamHandler.__init__(self, *args, **kwargs)


diff -r 71ceede82775407793c71670ae2a5f063ff68aa4 -r fdc44a69a4814a753dd1b7e9a738a8f1c99bba33 yt/gui/reason/html/app/controller/DataObjects.js
--- a/yt/gui/reason/html/app/controller/DataObjects.js
+++ b/yt/gui/reason/html/app/controller/DataObjects.js
@@ -45,7 +45,7 @@
 
     init: function() {
         this.application.addListener({
-           newdataobjects : {fn: this.refreshDataObjects, scope: this},
+           payloaddataobjects : {fn: this.refreshDataObjects, scope: this},
         });
         this.control({
             "#dataobjects": { itemcontextmenu:
@@ -57,8 +57,9 @@
         this.callParent(arguments);
     },
 
-    refreshDataObjects: function(objs) {
+    refreshDataObjects: function(payload) {
         /*console.log("Refreshing data objects");*/
+        var objs = payload['objs'];
         var root = this.getDataObjectsStore().getRootNode();
         root.removeAll();
         var pf;


diff -r 71ceede82775407793c71670ae2a5f063ff68aa4 -r fdc44a69a4814a753dd1b7e9a738a8f1c99bba33 yt/gui/reason/html/app/controller/Notebook.js
--- a/yt/gui/reason/html/app/controller/Notebook.js
+++ b/yt/gui/reason/html/app/controller/Notebook.js
@@ -48,6 +48,7 @@
     init: function() {
         this.application.addListener({
             payloadcell: {fn: this.addCell, scope: this},
+            payloadscript: {fn: this.loadScript, scope: this},
             executecell: {fn: this.executeCell, scope: this},
             wipeinput:   {fn: this.wipeInputLine, scope: this},
             blockinput:  {fn: this.blockInput, scope: this},
@@ -78,10 +79,18 @@
             input: cell['input'],
             output: cell['output'],
             raw_input: cell['raw_input'],
+            image_data: cell['image_data'],
             executiontime: cell['executiontime'],
         });
         this.application.fireEvent("scrolltobottom");
     },
+
+    loadScript: function(payload) {
+        console.log("Loading script ...");
+        this.getInputLine().setValue(payload['value']);
+        this.getInputLine()._lock = true;
+    },
+
     executeCell: function(line) {
         this.application.fireEvent("blockinput");
         console.log("Asked to execute " + line);
@@ -95,7 +104,11 @@
     },
     
     wipeInputLine: function() {
-        this.getInputLine().setValue("");
+        if(this.getInputLine()._lock == true) {
+            this.getInputLine()._lock = false;
+        } else {
+            this.getInputLine().setValue("");
+        }
     },
 
     blockInput: function() {
@@ -106,7 +119,6 @@
     allowInput: function() {
         this.getInputLine().removeCls("cell_waiting");
         this.getInputLine().setReadOnly(false);
-        console.log("Calling FileList");
         var application = this.application;
     },
 


diff -r 71ceede82775407793c71670ae2a5f063ff68aa4 -r fdc44a69a4814a753dd1b7e9a738a8f1c99bba33 yt/gui/reason/html/app/controller/ServerCommunication.js
--- a/yt/gui/reason/html/app/controller/ServerCommunication.js
+++ b/yt/gui/reason/html/app/controller/ServerCommunication.js
@@ -49,9 +49,6 @@
         this.heartbeat = this.taskRunner.start(
             {run: this.heartbeatCall,
              interval: 250});
-        this.dataObjectBeat = this.taskRunner.start(
-            {run: this.dataObjectsCall,
-             interval: 5000});
         this.callParent(arguments);
     },
 
@@ -70,18 +67,10 @@
         this.application.fireEvent('payload' + payload['type'], payload);
     },
 
-    dataObjectsCall: function() {
-        yt_rpc.ExtDirectParameterFileList.get_list_of_pfs({}, 
-            function(f, a) {
-                if (f == null) { return; }
-                reason.fireEvent("newdataobjects", f);
-        });
-    },
-
     heartbeatCall: function() {
         if (heartbeatRequest == true) return;
         heartbeatRequest = true;
-        console.log("Sending heartbeat");
+        /*console.log("Sending heartbeat");*/
         yt_rpc.ExtDirectREPL.heartbeat(
             {}, function(f, a) {
                 heartbeatRequest = false;


diff -r 71ceede82775407793c71670ae2a5f063ff68aa4 -r fdc44a69a4814a753dd1b7e9a738a8f1c99bba33 yt/gui/reason/html/app/controller/widgets/PlotWindow.js
--- a/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
+++ b/yt/gui/reason/html/app/controller/widgets/PlotWindow.js
@@ -252,9 +252,13 @@
             }
             var title = widget.templateManager.applyObject(obj, 'pwt');
             win = Ext.widget("plotwindowcreator", {title:title, obj:obj});
-            win.query("#weightField")[0].store = 
-                ['None'].concat(obj.field_list);
-            win.query("#field")[0].store = obj.field_list;
+            console.log(obj.field_list);
+            var field_list = [];
+            Ext.each(obj.field_list, function(f, i, af) {
+                field_list.push(f.text);
+            });
+            win.query("#weightField")[0].store = ['None'].concat(field_list);
+            win.query("#field")[0].store = field_list;
             win.query("#create")[0].on('click', makePlot);
             win.query("#cancel")[0].on('click', function(){win.destroy();});
             win.query("#maxDens")[0].on('change', toggleMaxDens);


diff -r 71ceede82775407793c71670ae2a5f063ff68aa4 -r fdc44a69a4814a753dd1b7e9a738a8f1c99bba33 yt/gui/reason/html/app/store/CellValues.js
--- a/yt/gui/reason/html/app/store/CellValues.js
+++ b/yt/gui/reason/html/app/store/CellValues.js
@@ -32,7 +32,9 @@
 Ext.define('Reason.store.CellValues', {
     extend: 'Ext.data.Store',
     id: 'cellvalues',
-    fields: ['input', 'output', 'raw_input', 'executiontime'],
+    fields: ['input', 'output', 'raw_input', 'executiontime', 
+        { name: 'image_data', type: 'string', defaultValue: '' }
+    ],
     data: [],
 });
 


diff -r 71ceede82775407793c71670ae2a5f063ff68aa4 -r fdc44a69a4814a753dd1b7e9a738a8f1c99bba33 yt/gui/reason/html/app/view/CellView.js
--- a/yt/gui/reason/html/app/view/CellView.js
+++ b/yt/gui/reason/html/app/view/CellView.js
@@ -38,6 +38,13 @@
     '<pre>{output}</pre><br/><br/>'
 );
 
+var imageDisplay = new Ext.XTemplate(
+    '<b>Image</b><br/><br/>',
+    '<hr>',
+    '<img src="data:image/png;base64,{image_data}">',
+    '<br/><br/>'
+);
+
 Ext.define('Reason.view.CellView', {
     extend: 'Ext.grid.Panel',
     alias: 'widget.notebookcells',
@@ -56,8 +63,15 @@
     features: [{
         ftype: 'rowbody',
         getAdditionalData: function(data, rowIndex, record, orig) {
+            var disp;
+            console.log(data);
+            if(data['image_data'] != '') {
+                disp = imageDisplay.apply(data);
+            } else {
+                disp = cellDisplay.apply(data);
+            }
             return {
-                rowBody: cellDisplay.apply(data),
+                rowBody: disp,
                 rowBodyCls: 'codeview',
                 rowBodyColspan: this.view.headerCt.getColumnCount(),
             };


diff -r 71ceede82775407793c71670ae2a5f063ff68aa4 -r fdc44a69a4814a753dd1b7e9a738a8f1c99bba33 yt/gui/reason/html/app/view/widgets/PlotWindowCreator.js
--- a/yt/gui/reason/html/app/view/widgets/PlotWindowCreator.js
+++ b/yt/gui/reason/html/app/view/widgets/PlotWindowCreator.js
@@ -88,6 +88,8 @@
                   fieldLabel: 'Field',
                   itemId: 'field',
                   store: [],
+                  displayField: 'text',
+                  valueield: 'text',
                   width: 200,
                   allowBlank:false,
                   triggerAction: 'all',
@@ -103,7 +105,9 @@
                   xtype:'combo',
                   fieldLabel: 'Weight Field',
                   itemId: 'weightField',
-                  store: ['None'],
+                  store: [{text:'None'},],
+                  displayField: 'text',
+                  valueield: 'text',
                   width: 200,
                   allowBlank:false,
                   triggerAction: 'all',


diff -r 71ceede82775407793c71670ae2a5f063ff68aa4 -r fdc44a69a4814a753dd1b7e9a738a8f1c99bba33 yt/gui/reason/html/help.html
--- a/yt/gui/reason/html/help.html
+++ b/yt/gui/reason/html/help.html
@@ -62,7 +62,7 @@
 }
 
 a {
-    /*text-decoration: none;*/
+    text-decoration: none;
 }
 
 a:link {
@@ -84,17 +84,15 @@
 </style><body><div class="yt_logo">
-<h1>yt:</h1>
-<p>because your data isn't going to analyze itself!</p>
+<h1>yt</h1><ul class="quick_list">
+<li><a href="http://yt-project.org/">home</a></li><li><a href="http://yt-project.org/doc/">docs</a></li>
-<li><a href="http://yt-project.org/wiki/Gallery">gallery</a> ( <a href="video_gallery.html">video</a> )</li>
-<li><a href="http://yt-project.org/wiki">wiki</a></li>
-<li><a href="http://yt-project.org/doc/orientation.html">quick start</a></li>
-<li><a href="http://yt-project.org/newticket">report a bug</a></li>
-<li><a href="http://yt-project.org/browser">source</a></li>
-<li><a href="principles.html">principles</a></li>
-<li><a href="http://blog.enzotools.org/">development blog</a></li>
+<li><a href="https://bitbucket.org/yt_analyis/yt/">development page</a></li>
+<li><a href="https://bitbucket.org/yt_analyis/yt/newticket">report a bug</a></li>
+<li><a href="http://yt-project.org/irc.html">chat</a></li>
+<li> </li>
+<li><a href="http://yt-project.org/docs/2.3/interacting/reason.html">reason manual</a></li></ul></div><div class="faq">
@@ -117,28 +115,22 @@
 images will be returned in the window.  You can click on these images to view
 them at full-size.</p>
 
-<h2>Using the interactive plot window</h2>
-<p>As you execute cells and load parameter files from disk, these parameter
-files will get added to the tree view on the left, along with any objects that
-have been created from them.</p>
+<h2>Interactive Visualization</h2>
+<p>Once you have loaded data off disk, either by loading it in the Notebook,
+or choosing "Load File" from the menu, you can right click on any object
+in the left hand menu to choose different visualization options.</p>
 
-<p>Over time, these objects will expose right-click events to create plot
-windows, as well as drag-and-drop functionality.</p>
+<p>You can also supply files on the command line when starting Reason, or run
+with "-f" to search for them in the current directory.</p>
 
-<h2>Saving and loading sessions</h2>
-<p>There are three methods for saving your work.  You can click "Download" to
-download a copy of your session on your local machine.  By clicking "Save" you
-can save a copy on the server on which Reason is running.  By clicking
-"Pastebin" you can send a copy of it to the <a
-href="http://paste.yt-project.org/">yt pastebin</a>.</p>
-
-<p>If you use the command 'load_script' and supply it a file the server can
-find locally, it will read that file in and populate the contents of your next
-submission cell with it.</p>
+<h2>Delivering Images and Scripts</h2>
+<p>The command <tt>deliver_image('filename.png')</tt> will display the file
+<tt>filename.png</tt> in the output window.  The command <tt>load_script('filename.py')</tt>
+will fill the execution area with the script <tt>filename.py</tt>.</p><h2>How to Quit</h2>
-<p>To quit, simply press Ctrl-C in the console window that you ran "yt serve"
-within.</p>
+<p>To quit, either choose "Quit" from the menu or press Ctrl-C in the console
+window that you ran "yt serve" within.</p></div></body>


diff -r 71ceede82775407793c71670ae2a5f063ff68aa4 -r fdc44a69a4814a753dd1b7e9a738a8f1c99bba33 yt/gui/reason/html/index.html
--- a/yt/gui/reason/html/index.html
+++ b/yt/gui/reason/html/index.html
@@ -8,25 +8,24 @@
     <link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Inconsolata"><!-- LIBS -->
-    <link rel="stylesheet" type="text/css" href="resources/extjs-4.1.0/resources/css/ext-all-gray.css">
+    <link rel="stylesheet" type="text/css" href="reason-js/resources/css/ext-all-gray.css"><link rel="stylesheet" type="text/css" href="reason/resources/css/style.css"><link rel="stylesheet" type="text/css" href="reason/resources/css/CheckHeader.css"><link rel="stylesheet" type="text/css" href="highlighter.css">
 
-    <script type="text/javascript" src="resources/extjs-4.1.0/ext-all-debug.js"></script>
+    <script type="text/javascript" src="reason-js/ext-all.js"></script><script type="text/javascript" src="reason/app.js"></script><script type="text/javascript" src="ext-repl-api.js"></script>
-    <script type="text/javascript" src="resources/ext-pflist-api.js"></script><!-- Additional Ext UX files --><script type="text/javascript" src="reason/resources/ux/CheckColumn.js"></script><!-- LEAFLET STUFF -->
-    <script type="text/javascript" src="reason/resources/leaflet/leaflet.js"></script>
-    <link rel="stylesheet" href="reason/resources/leaflet/leaflet.css" />
+    <script type="text/javascript" src="reason-js/leaflet/leaflet.js"></script>
+    <link rel="stylesheet" href="reason-js/leaflet/leaflet.css" /><!-- XTK STUFF -->
-    <script type="text/javascript" src="reason/xtk_edge.js"></script>
+    <script type="text/javascript" src="reason-js/xtk_edge.js"></script></head><body>


diff -r 71ceede82775407793c71670ae2a5f063ff68aa4 -r fdc44a69a4814a753dd1b7e9a738a8f1c99bba33 yt/gui/reason/html/js/functions.js
--- a/yt/gui/reason/html/js/functions.js
+++ /dev/null
@@ -1,687 +0,0 @@
-/**********************************************************************
-Functions for Reason
-
-Author: Cameron Hummels <chummels at gmail.com>
-Affiliation: Columbia
-Author: Jeffrey S. Oishi <jsoishi at gmail.com>
-Affiliation: KIPAC/SLAC/Stanford
-Author: Britton Smith <brittonsmith at gmail.com>
-Affiliation: MSU
-Author: Matthew Turk <matthewturk at gmail.com>
-Affiliation: Columbia University
-Homepage: http://yt-project.org/
-License:
-  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
-
-  This file is part of yt.
-
-  yt is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 3 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-***********************************************************************/
-
-function cell_finished(result) {
-    var new_log = false;
-    var cell_resulted = false;
-    var cell;
-    Ext.each(result, 
-    function(payload, index) {
-        if (payload['type'] == 'shutdown') {
-            reason.task_runner.stop(heartbeat);
-            reason.heartbeat_request = true;
-            return;
-        } else if (payload['type'] == 'cell_results') {
-            text = "<pre>"+payload['output']+"</pre>";
-            formatted_input = payload['input']
-            cell = new_cell(formatted_input, text, payload['raw_input']);
-            OutputContainer.add(cell);
-            OutputContainer.doLayout();
-            notebook.doLayout();
-            if (repl_input.locked == true) {
-                /* Assume only one locking level */
-                repl_input.locked = false;
-            } else {
-                repl_input.get("input_line").setValue("");
-            }
-            if (OutputContainer.items.length > 1) {
-                OutputContainer.body.dom.scrollTop = 
-                OutputContainer.body.dom.scrollHeight -
-                cell.body.dom.scrollHeight - 20;
-            }
-            cell_resulted = true;
-        } else if (payload['type'] == 'png_string') {
-            OutputContainer.add(new Ext.Panel({
-                autoEl:{
-                    tag:'img', 
-                    width:'25%',
-                    src:"data:image/png;base64," + payload['image_data'],
-                    id:"payload_image_" + number_images,
-                    onClick: "display_image('payload_image_" + number_images + "');"
-		        }
-            }));
-	        OutputContainer.doLayout();
-	        number_images++;
-        } else if (payload['type'] == 'cell_contents') {
-	        var input_line = repl_input.get("input_line");
-	        input_line.setValue(payload['value']);
-            repl_input.locked = true;
-        } else if (payload['type'] == 'log_entry') {
-            reason.log(payload['log_entry']);
-            new_log = true;
-        } else if (payload['type'] == 'widget') {
-            var widget_type = payload['widget_type'];
-            var widget = new widget_types[widget_type](payload['varname'],
-                                                       payload['data']);
-            widget_list[widget.id] = widget;
-            /*
-               Sometimes instantiating a widget adds some objects ...
-               Plus, often when creating a widget we disable the 
-               entry of data and whatnot. 
-            */
-            cell_resulted = true;
-        } else if (payload['type'] == 'widget_payload') {
-            var widget = widget_list[payload['widget_id']];
-            widget.accept_results(payload);
-        } else {
-            alert("Didn't know how to process " + payload['type']);
-        }
-    });
-    if (new_log == true){
-        reason.log_scroll()
-    }
-    if (cell_resulted == true) {
-        enable_input();
-    }
-}
-
-function display_image(image_id) {
-    var image = Ext.get(image_id);
-    var src = image.dom.src;
-    var virtualdom = '<html><title>Image Viewer</title><body><img src="' 
-        + src + '"/></body></html>',
-    prev = window.open('', 'image_viewer');
-    prev.document.open();
-    prev.document.write(virtualdom);
-    prev.document.close();
-}
-
-// Create a tree in the left panel with the pfs and their objects.
-function fill_tree(my_pfs) {
-    treePanel.root.removeAll();
-    Ext.each(my_pfs, function(pf, index) {
-        treePanel.root.appendChild(new Ext.tree.TreeNode({
-            text: pf.name,
-            objdata: {fn: pf.filename, varname: pf.varname, type: 'pf',
-                      field_list: pf.field_list},
-            leaf:false, 
-            expanded:true, 
-            iconCls: 'pf_icon'}));
-        this_pf = treePanel.root.lastChild
-        Ext.each(pf.objects, function(obj, obj_index) {
-            this_pf.appendChild(new Ext.tree.TreeNode(
-                {text: obj.name,
-                 leaf: true,
-                 iconCls: 'data_obj',
-                 objdata: {varname: obj.varname, type: 'obj',
-                           pfdata: this_pf.attributes.objdata},
-                 }));
-        });
-    });
-}
-
-function new_cell(input, result, raw_input) {
-    var name = "cell_" + cell_count;
-    var CellPanel = new Ext.Panel(
-        { 
-            id: name, 
-            //title: "Cell " + cell_count,
-            items: [
-                { xtype:'panel',
-                  layout: 'hbox',
-                  id:name+"_input",
-                  items: [
-                    { xtype:'panel',
-                      html:input,
-                      flex:1,
-                      boxMinHeight: 40,
-                    },
-                    { xtype: 'button',
-                      width: 24,
-                      height: 24,
-                      iconCls: 'upload',
-                      tooltip: 'Upload to Pastebin',
-                      listeners: {
-                          click: function(f, e) {
-                            yt_rpc.ExtDirectREPL.paste_text({to_paste:raw_input},
-                              function(f, a) {
-                                if (a.result['status'] == 'SUCCESS') {
-                                    var alert_text = 'Pasted cell to:<br>' + 
-                                    a.result['site']
-                                    var alert_text_rec = 'Pasted cell to: ' + 
-                                    a.result['site']
-                                    Ext.Msg.alert('Pastebin', alert_text);
-                                    var record = new logging_store.recordType(
-                                        {record: alert_text_rec });
-                                    logging_store.add(record, number_log_records++);
-                              }
-                            });
-                          }
-                        }
-                    },
-                    { xtype: 'button',
-                      width: 24,
-                      height: 24,
-                      iconCls: 'doubleuparrow',
-                      tooltip: 'Copy into current cell',
-                      listeners: {
-                          click: function(f, e) {
-                            repl_input.get('input_line').setValue(raw_input);
-                          }
-                      },
-                    },
-                  ],
-                },
-                { xtype:'panel',
-                  layout: 'hbox',
-                  items: [
-                    { xtype:'panel',
-                      id:name+"_result",
-                      autoScroll:true,
-                      flex: 1,
-                      html:result,
-                      boxMinHeight: 40,
-                    },
-                  ],
-                },
-            ]
-        }
-    );
-    cell_count++;
-    return CellPanel;
-}
-
-function getGridViewerHandler(node){
-function gridViewerHandler(item, pressed){
-    yt_rpc.ExtDirectREPL.create_grid_viewer(
-        {pfname:node.attributes.objdata.varname},
-        handle_result);
-}
-return gridViewerHandler;
-}
-
-function getGridDataViewerHandler(node){
-function gridDataViewerHandler(item, pressed){
-    yt_rpc.ExtDirectREPL.create_grid_dataview(
-        {pfname:node.attributes.objdata.varname},
-        handle_result);
-}
-return gridDataViewerHandler;
-}
-
-function getStreamlineViewerHandler(node){
-function streamlineViewerHandler(item, pressed){
-    yt_rpc.ExtDirectREPL.create_streamline_viewer(
-        {pfname:node.attributes.objdata.varname},
-        handle_result);
-}
-return streamlineViewerHandler;
-}
-
-function getIsocontourViewerHandler(node){
-function isocontourViewerHandler(item,pressed){
-    var win = new Ext.Window({
-        layout:'fit',
-        width:320,
-        height:250,
-        modal:true,
-        resizable:false,
-        draggable:false,
-        border:false,
-        title:'Isocontour Extraction in' + node,
-        items: [{
-            xtype: 'form', // FormPanel
-            labelWidth:80,
-            frame:true,
-            items: [{
-                xtype:'combo',
-                fieldLabel: 'Field',
-                id: 'field',
-                store:node.attributes.objdata.field_list,
-                width: 200,
-                allowBlank:false,
-                value: 'Density',
-                triggerAction: 'all',
-            },{
-                xtype:'combo',
-                fieldLabel: 'Sampling Field',
-                id: 'extract_field',
-                store:node.attributes.objdata.field_list,
-                width: 200,
-                allowBlank:false,
-                value: 'Temperature',
-                triggerAction: 'all',
-            },{
-                xtype:'textfield',
-                fieldLabel: 'Value',
-                id: 'value',
-                value: '1e-25',
-                width: 90,
-                allowBlank:false,
-            }],
-            buttons: [
-                {
-                    text: 'Extract',
-                    handler: function(b, e){
-                        var field = Ext.get("field").getValue();
-                        var value = Ext.get("value").getValue();
-                        var sampling_field = Ext.get("extract_field").getValue();
-                        yt_rpc.ExtDirectREPL.create_isocontours({
-                            pfname:node.attributes.objdata.varname,
-                            field:field, value:value,
-                            sampling_field:sampling_field},
-                          handle_result);
-                        disable_input();
-                        win.close();
-                    }
-                },{
-                    text: 'Cancel',
-                    handler: function(b, e){
-                        win.close();
-                    }
-                }
-            ]
-        }]
-    });
-    win.show(this);
-}
-return isocontourViewerHandler;
-}
-
-function getSliceHandler(node){
-function sliceHandler(item,pressed){
-    var win = new Ext.Window({
-        layout:'fit',
-        width:320,
-        height:250,
-        modal:true,
-        resizable:false,
-        draggable:false,
-        border:false,
-        title:'Slice Details for ' + node,
-        items: [{
-            xtype: 'form', // FormPanel
-            labelWidth:80,
-            frame:true,
-            items: [{
-                xtype:'textfield',
-                fieldLabel: 'Center X',
-                id: 'slice_x_center',
-                value: '0.5',
-                width: 90,
-                allowBlank:false,
-            },{
-                xtype:'textfield',
-                fieldLabel: 'Center Y',
-                id: 'slice_y_center',
-                value: '0.5',
-                width: 90,
-                allowBlank:false,
-            },{
-                xtype:'textfield',
-                fieldLabel: 'Center Z',
-                id: 'slice_z_center',
-                value: '0.5',
-                width: 90,
-                allowBlank:false,
-            },{
-                xtype:'combo',
-                fieldLabel: 'Axis',
-                id: 'slice_axis',
-                store:['X','Y','Z'],
-                width: 90,
-                allowBlank:false,
-                value: 'X',
-                triggerAction: 'all',
-            },{
-                xtype:'checkbox',
-                fieldLabel: 'Center on Max',
-                id: 'max_dens',
-                width: 90,
-                allowBlank:false,
-                handler: function(checkbox, checked) {
-                    if (checked == true) {
-                        this.ownerCt.get("slice_x_center").disable();
-                        this.ownerCt.get("slice_y_center").disable();
-                        this.ownerCt.get("slice_z_center").disable();
-                    } else {
-                        this.ownerCt.get("slice_x_center").enable();
-                        this.ownerCt.get("slice_y_center").enable();
-                        this.ownerCt.get("slice_z_center").enable();
-                    }
-                }
-            },{
-                xtype:'combo',
-                fieldLabel: 'Field',
-                id: 'slice_field',
-                store:node.attributes.objdata.field_list,
-                width: 200,
-                allowBlank:false,
-                value: 'Density',
-                triggerAction: 'all',
-            }],
-            buttons: [
-                {
-                    text: 'Slice',
-                    handler: function(b, e){
-                        var center = [Ext.get("slice_x_center").getValue(),
-                                      Ext.get("slice_y_center").getValue(),
-                                      Ext.get("slice_z_center").getValue()];
-                        var axis = Ext.get("slice_axis").getValue();
-                        var field = Ext.get("slice_field").getValue();
-                        var onmax = Ext.get("max_dens").getValue();
-                        yt_rpc.ExtDirectREPL.create_slice({
-                            pfname:node.attributes.objdata.varname,
-                            center: center, axis:axis, field:field, onmax:onmax},
-                          handle_result);
-                        disable_input();
-                        win.close();
-                    }
-                },{
-                    text: 'Cancel',
-                    handler: function(b, e){
-                        win.close();
-
-                    }
-                }
-            ]
-        }]
-    });
-    win.show(this);
-}
-return sliceHandler;
-}
-
-function widget_call(varname, method) {
-    var fcall = varname + "." + method;
-    yt_rpc.ExtDirectREPL.execute(
-        {code: fcall}, cell_finished);
-}
-
-function getPhasePlotHandler(node){
-function phasePlotHandler(item,pressed){
-    var win = new Ext.Window({
-        layout:'fit',
-        width:370,
-        height:220,
-        modal:true,
-        resizable:false,
-        draggable:false,
-        border:false,
-        title:'Phase Plot Details for ' + node,
-        items: [{
-            xtype: 'form', // FormPanel
-            labelWidth:80,
-            frame:true,
-            items: [ {
-                xtype:'combo',
-                fieldLabel: 'X Field',
-                id: 'x_field',
-                store:node.attributes.objdata.pfdata.field_list,
-                width: 230,
-                allowBlank:false,
-                triggerAction: 'all',
-                value: 'Density'
-            },{
-                xtype:'combo',
-                fieldLabel: 'Y Field',
-                id: 'y_field',
-                store:node.attributes.objdata.pfdata.field_list,
-                width: 230,
-                allowBlank:false,
-                triggerAction: 'all',
-                value: 'Temperature'
-            },{
-                xtype:'combo',
-                fieldLabel: 'Z Field',
-                id: 'z_field',
-                store:node.attributes.objdata.pfdata.field_list,
-                width: 230,
-                allowBlank:false,
-                triggerAction: 'all',
-                value: 'CellMassMsun'
-            },{
-                xtype:'combo',
-                fieldLabel: 'Weight Field',
-                id: 'weight',
-                store:['None'].concat(node.attributes.objdata.pfdata.field_list),
-                width: 230,
-                allowBlank:false,
-                triggerAction: 'all',
-                value: 'None'
-            }],
-            buttons: [
-                {
-                    text: 'Calculate',
-                    handler: function(b, e){
-                        var x_field = Ext.get("x_field").getValue();
-                        var y_field = Ext.get("y_field").getValue();
-                        var z_field = Ext.get("z_field").getValue();
-                        var weight = Ext.get("weight").getValue();
-                        yt_rpc.ExtDirectREPL.create_phase({
-                                objname: node.attributes.objdata.varname,
-                                /* Mirror image varnames ... */
-                                field_x: x_field,
-                                field_y: y_field,
-                                field_z: z_field,
-                                weight: weight,
-                                },
-                              handle_result);
-                        disable_input();
-                        win.close();
-                    }
-                },{
-                    text: 'Cancel',
-                    handler: function(b, e){win.close()}
-                }
-            ]
-        }]
-    });
-    win.show(this);
-}
-return phasePlotHandler;
-}
-
-function getProjectionHandler(node){
-function projectionHandler(item,pressed){
-    var win = new Ext.Window({
-        layout:'fit',
-        width:370,
-        height:220,
-        modal:true,
-        resizable:false,
-        draggable:false,
-        border:false,
-        title:'Projection Details for ' + node,
-        items: [{
-            xtype: 'form', // FormPanel
-            labelWidth:80,
-            frame:true,
-            items: [{
-                xtype:'combo',
-                fieldLabel: 'Axis',
-                id: 'axis',
-                store:['X','Y','Z'],
-                width: 90,
-                allowBlank:false,
-                triggerAction: 'all',
-                value: 'X',
-            },{
-                xtype:'checkbox',
-                fieldLabel: 'Center on Max',
-                id: 'max_dens',
-                width: 90,
-                allowBlank:false,
-                /* No handler, because no center */
-            },{
-                xtype:'combo',
-                fieldLabel: 'Field',
-                id: 'field',
-                store:node.attributes.objdata.field_list,
-                width: 230,
-                allowBlank:false,
-                triggerAction: 'all',
-                value: 'Density'
-            },{
-                xtype:'combo',
-                fieldLabel: 'Weight Field',
-                id: 'weightField',
-                store:['None'].concat(node.attributes.objdata.field_list),
-                width: 230,
-                allowBlank:false,
-                triggerAction: 'all',
-                value: 'None'
-            }],
-            buttons: [
-                {
-                    text: 'Project',
-                    handler: function(b, e){
-                        var axis = Ext.get("axis").getValue();
-                        var field = Ext.get("field").getValue();
-                        var weight = Ext.get("weightField").getValue();
-                        var onmax = Ext.get("max_dens").getValue();
-                        yt_rpc.ExtDirectREPL.create_proj({
-                                pfname: node.attributes.objdata.varname,
-                                axis: axis, field: field, weight: weight,
-                                onmax: onmax},
-                              handle_result);
-                        disable_input();
-                        win.close();
-                    }
-                },{
-                    text: 'Cancel',
-                    handler: function(b, e){win.close()}
-                }
-            ]
-        }]
-    });
-    win.show(this);
-}
-return projectionHandler;
-}
-
-function getSphereCreator(node){
-function sphereCreator(item,pressed){
-    var win = new Ext.Window({
-        layout:'fit',
-        width:320,
-        height:250,
-        modal:true,
-        resizable:false,
-        draggable:false,
-        border:false,
-        title:'Sphere Creator ' + node,
-        items: [{
-            xtype: 'form', // FormPanel
-            labelWidth:80,
-            frame:true,
-            items: [{
-                xtype:'textfield',
-                fieldLabel: 'Center X',
-                id: 'slice_x_center',
-                value: '0.5',
-                width: 90,
-                allowBlank:false,
-            },{
-                xtype:'textfield',
-                fieldLabel: 'Center Y',
-                id: 'slice_y_center',
-                value: '0.5',
-                width: 90,
-                allowBlank:false,
-            },{
-                xtype:'textfield',
-                fieldLabel: 'Center Z',
-                id: 'slice_z_center',
-                value: '0.5',
-                width: 90,
-                allowBlank:false,
-            },{
-                xtype:'textfield',
-                fieldLabel: 'Radius',
-                id: 'radius_value',
-                value: '0.5',
-                width: 90,
-                allowBlank:false,
-            },{
-                xtype:'combo',
-                fieldLabel: 'Unit',
-                id: 'radius_unit',
-                store:['unitary', '1', 'mpc', 'kpc', 'pc', 'au', 'rsun', 'cm'],
-                width: 90,
-                allowBlank:false,
-                value: 'Unitary',
-                triggerAction: 'all',
-            },{
-                xtype:'checkbox',
-                fieldLabel: 'Center on Max',
-                id: 'max_dens',
-                width: 90,
-                allowBlank:false,
-                handler: function(checkbox, checked) {
-                    if (checked == true) {
-                        this.ownerCt.get("slice_x_center").disable();
-                        this.ownerCt.get("slice_y_center").disable();
-                        this.ownerCt.get("slice_z_center").disable();
-                    } else {
-                        this.ownerCt.get("slice_x_center").enable();
-                        this.ownerCt.get("slice_y_center").enable();
-                        this.ownerCt.get("slice_z_center").enable();
-                    }
-                }
-            }],
-            buttons: [
-                {
-                    text: 'Slice',
-                    handler: function(b, e){
-                        var center = [Ext.get("slice_x_center").getValue(),
-                                      Ext.get("slice_y_center").getValue(),
-                                      Ext.get("slice_z_center").getValue()];
-                        var onmax = Ext.get("max_dens").getValue();
-                        var radius = [Ext.get("radius_value").getValue(),
-                                      Ext.get("radius_unit").getValue()]
-                        objargs = {radius: radius}
-                        if (onmax == true) {
-                            objargs['center'] = 'max';
-                        } else {
-                            objargs['center'] = center;
-                        }
-                        yt_rpc.ExtDirectREPL.object_creator({
-                            pfname:node.attributes.objdata.varname,
-                            objtype:'sphere', objargs:objargs},
-                          handle_result);
-                        disable_input();
-                        win.close();
-                    }
-                },{
-                    text: 'Cancel',
-                    handler: function(b, e){
-                        win.close();
-
-                    }
-                }
-            ]
-        }]
-    });
-    win.show(this);
-}
-return sphereCreator;
-}


diff -r 71ceede82775407793c71670ae2a5f063ff68aa4 -r fdc44a69a4814a753dd1b7e9a738a8f1c99bba33 yt/gui/reason/html/js/reason.js
--- a/yt/gui/reason/html/js/reason.js
+++ /dev/null
@@ -1,383 +0,0 @@
-/**********************************************************************
-The main GUI facility for Reason
-
-Author: Cameron Hummels <chummels at gmail.com>
-Affiliation: Columbia
-Author: Jeffrey S. Oishi <jsoishi at gmail.com>
-Affiliation: KIPAC/SLAC/Stanford
-Author: Britton Smith <brittonsmith at gmail.com>
-Affiliation: MSU
-Author: Matthew Turk <matthewturk at gmail.com>
-Affiliation: Columbia University
-Homepage: http://yt-project.org/
-License:
-  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
-
-  This file is part of yt.
-
-  yt is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 3 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-***********************************************************************/
-
-Ext.app.Module = function(config){
-    Ext.apply(this, config);
-    Ext.app.Module.superclass.constructor.call(this);
-    this.init();
-}
-
-Ext.extend(Ext.app.Module, Ext.util.Observable, {
-    init : Ext.emptyFn
-});
-
-Reason = new Ext.app.App({
-  init: function() {
-    if (typeof(console) != "undefined") {
-        console.log('Mitchell!\nPardon me! Mitchell!')
-    }
-    this.setup_viewport();
-    // Go ahead and create the TreePanel now so that we can use it below
-    // get a reference to the HTML element with id "hideit" and add a click listener to it 
-    Ext.get("hideit").on('click', function(){
-        // get a reference to the Panel that was created with id = 'west-panel' 
-	    var w = Ext.getCmp('west-panel');
-        // expand or collapse that Panel based on its collapsed property state
-        // need to make room for six sour cream burritos
-        w.collapsed ? w.expand() : w.collapse();
-    });
-
-    /* Now we create our record store. */
-    this.logging_store = new Ext.data.Store({
-        fields: [{name:'record'}],
-        reader: new Ext.data.ArrayReader({}, [{name: 'record'}]),
-    });
-
-    this.widget_types = {}
-    this.widget_list = {}
-    this.number_log_records = 0;
-    this.number_images = 0;
-    this.cell_count = 0;
-    this.notebook = viewport.get("center-panel").get("notebook");
-    this.status_region = viewport.get("status-region");
-  },
-
-  setup_viewport: function() {
-    this.viewport = new Ext.Viewport({
-        layout: 'border',
-        items: [
-		// lazily created panel (xtype:'panel' is default)
-            {
-                xtype: 'grid',
-                store: logging_store,
-                defaults: { width: 800 },
-                columns: [ {id:'record', 
-                    sortable: false,
-                    width:800} ],
-                autofill: true,
-                region: 'south',
-                id: "status-region",
-                cls: "status-logger",
-                split: true,
-                height: 100,
-                maxSize: 200,
-                collapsible: true,
-                title: 'Status',
-                margins: '0 0 0 0',
-            }, {
-                region: 'west',
-                id: 'west-panel', // see Ext.getCmp() below
-                title: 'Data Objects',
-                split: true,
-                width: 200,
-                minSize: 175,
-                maxSize: 400,
-                collapsible: true,
-                margins: '0 0 0 5',
-                layout: {
-                    type: 'anchor',
-                },
-                items: [{
-                        xtype: 'toolbar',
-                        items: [ main_menu ],
-                    },
-                    treePanel,
-                ]
-		  // in this instance the TabPanel is not wrapped by another panel
-		  // since no title is needed, this Panel is added directly
-		  // as a Container
-            },{
-                xtype: 'tabpanel',
-                region: 'center', 
-                id: 'center-panel',
-                deferredRender: false,
-                activeTab: 0,     
-                items: [{
-                        title: 'YT',
-                        id: 'notebook',
-                        layout: 'vbox',
-                        layoutConfig: {align:'stretch'},
-                        closable: false,
-                        autoScroll: false,
-                        iconCls: 'console',
-                        items: [InputContainer, OutputContainer]
-                    }, 
-                ]
-            }
-        ]
-    });
-  },
-
-  log : function(text) {
-    this.logging_store.add({record:text}, this.number_log_records++);
-  },
-
-  log_scroll : function() {
-    this.status_region.getView().focusRow(number_log_records-1);
-  },
-
-  handle_result : function(f, a) {
-    if(a.status == false){
-        Ext.Msg.alert("Error", "Something has gone wrong.");
-        examine = {f: f, a: a};
-        return;
-    }
-    this.cell_finished(a.result);
-  },
-
-  start_heartbeat : function() {
-    this.task_runner = new Ext.util.TaskRunner();
-    this.heartbeat_request = false;
-    this.number_heartbeats = 0;
-    this.heartbeat = {
-    run:
-      function(){ if (this.heartbeat_request == true) return; 
-        this.heartbeat_request = true;
-        yt_rpc.ExtDirectREPL.heartbeat(
-            {}, function(f, a) {
-            this.heartbeat_request = false;
-            if (f != null) {
-                handle_result(f, a);
-            }})},
-    interval: 250};
-
-    this.task_runner.start(heartbeat);
-  },
-
-  enable_input : function() {
-    repl_input.body.removeClass("cell_waiting");
-    repl_input.get('input_line').setReadOnly(false);
-    repl_input.get("input_line").focus();
-    yt_rpc.ExtDirectParameterFileList.get_list_of_pfs({}, fill_tree);
-  },
-
-  disable_input : function() {
-    this.InputCell.get('input_line').setReadOnly(true);
-    this.InputCell.body.addClass("cell_waiting");
-  },
-});
-
-Reason.Interpreter = function() { 
-    var interpreter = this;
-    this.execute = function() {
-        this.disable_input();
-        yt_rpc.ExtDirectREPL.execute({
-            code:this.InputForm.get('input_line').getValue()},
-        this.handle_result);
-    };
-    this.get_contents() {
-        return this.InputForm.get('input_line').getValue();
-    }
-    this.set_contents(contents, focus) {
-        this.InputForm.get('input_line').setValue(contents);
-        if (focus == true) {
-            this.InputForm.get('input_line').focus();
-        }
-    }
-    this.InputForm = new Ext.FormPanel({
-        title: 'YT Input',
-        url: 'push',
-        flex: 0.2,
-        layout: 'fit',
-        padding: 5,
-        height: '100%',
-        flex: 1.0,
-        items: [{
-            id: 'input_line',
-            xtype: 'textarea',
-            width: '100%',
-            autoScroll: true,
-            name: 'line',
-            allowBlank: 'True',
-            bodyStyle: 'font-family: "monospace";',
-            listeners: {
-                specialkey: function(f, e){
-                    if (e.getKey() == e.ENTER) {
-                        Reason.Interpreter.execute();
-                    }
-                },
-                afterrender: function(f, e){
-                    //var input_line_drop_target_el = repl_input.get("input_line").el.dom;
-                    var input_line_drop_target_el = repl_input.body.dom;
-
-                    var input_line_drop_target = new Ext.dd.DropTarget(input_line_drop_target_el, {
-                        ddGroup     : 'pfDDgroup',
-                        notifyEnter : function(ddSource, e, data) {
-                            repl_input.body.stopFx();
-                            repl_input.body.highlight();
-                        },
-                        notifyDrop  : function(ddSource, e, data){
-
-                            var varname = data.node.attributes.objdata.varname;
-                            /* There is possibly a better way to do this, where it's also inserted correctly. */
-                            var line = Reason.Interpreter.get_contents();
-                            Reason.interpreter.set_contents(line + varname, true);
-                            return(true);
-                        }
-                    });
-                },
-            },
-        },],
-    });
-    this.InputContainer = new Ext.Panel({
-        title: 'YT Input',
-        flex: 0.3,
-        layout: {type: 'hbox',
-                 pack: 'start',
-                 align: 'stretch',
-                 },
-        items: [ interpreter.InputForm,
-                { xtype: 'button',
-                  width: 24,
-                  height: 24,
-                  iconCls: 'doubledownarrow',
-                  tooltip: 'Execute Cell',
-                  listeners: {
-                      click: function(f, e) { interpreter.execute(); }
-                  },
-                }
-               ]
-    });
-
-
-var OutputContainer = new Ext.Panel({
-    title: 'YT Output',
-    id: 'output_container',
-    autoScroll: true,
-    flex: 0.8,
-    items: []
-});
-
-TreePanel = function(
-new Ext.tree.TreePanel({
-    iconCls: 'nav',
-    id: 'tree-panel',
-    layout: 'anchor',
-    region:'west',
-    split: true,
-    anchor: '100% -35',
-    minSize: 150,
-    autoScroll: true,
-    rootVisible: false,
-    ddGroup: 'pfDDgroup',
-    enableDD: true,
-    root:new Ext.tree.TreeNode({
-        expanded:true,
-        leaf:false,
-        text:''
-    }),
-    listeners: {
-        render: {
-            fn: function() {
-                Ext.getBody().on("contextmenu", Ext.emptyFn,
-                null, {preventDefault: true});
-            }
-        },
-        dblclick: {
-            fn: function(node, e) {
-                treePanel.fireEvent("contextmenu", node, e);
-            }
-        },
-        contextmenu: {
-            fn: function(node, event){
-                var rightclickMenu;
-                if (node.attributes.objdata.type == 'obj') {
-                  rightClickMenu = new Ext.menu.Menu({
-                      items: [
-                          {
-                              text: 'Phase Plot',
-                              handler: getPhasePlotHandler(node),
-                          }, 
-                      ]
-                  });
-                } else if (node.attributes.objdata.type == 'pf') {
-                  rightClickMenu = new Ext.menu.Menu({
-                      items: [
-                          {
-                              text: 'View Grids',
-                              handler: getGridViewerHandler(node),
-                          }, {
-                              text: 'View Isocontour',
-                              handler: getIsocontourViewerHandler(node),
-                          }, {
-                              text: 'View Grid Data',
-                              handler: getGridDataViewerHandler(node),
-                          }, {
-                              text: 'Open slice',
-                              handler: getSliceHandler(node),
-                          }, {
-                              text: 'Open projection',
-                              handler: getProjectionHandler(node),
-                          /*}, {
-                              text: 'Create Sphere',
-                              handler: getSphereCreator(node), */
-                          }, /*{
-                              text: 'View Streamlines',
-                              handler: getStreamlineViewerHandler(node),
-                          }, */
-                      ]
-                  });
-                }
-                rightClickMenu.showAt(event.xy);
-            }
-        }
-    }
-});
-
-var reason;
-var examine;
-
-Ext.onReady(function(){
-    Ext.BLANK_IMAGE_URL = 'resources/resources/images/default/s.gif';
-
-    // NOTE: This is an example showing simple state management. During development,
-    // it is generally best to disable state management as dynamically-generated ids
-    // can change across page loads, leading to unpredictable results.  The developer
-    // should ensure that stable state ids are set for stateful components in real apps.
-    // it's a cold day for pontooning.
-    Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
-    reason = Reason()
-    reason.log('Welcome to yt.');
-    reason.log('After entering a line of code in the YT Input field, press shift-enter to evaluate.');
-    reason.log('4d3d3d3 engaged.');
-
-    if (!Ext.state.Manager.get("reason_welcomed", false)) {
-        Ext.MessageBox.alert("Reason v0.5",
-        "Welcome to Reason.  <br>Treat the 'YT Input' field as a YT/python intepreter.<br>Press shift-enter to evaluate.",
-        function(b,e){ repl_input.get("input_line").focus(); });
-        Ext.state.Manager.set("reason_welcomed", true);
-    } else { 
-        repl_input.get("input_line").focus();
-    }
-
-    /* Set up the heartbeat */
-    reason.start_heartbeat();
-});


diff -r 71ceede82775407793c71670ae2a5f063ff68aa4 -r fdc44a69a4814a753dd1b7e9a738a8f1c99bba33 yt/gui/reason/html/resources/leaflet/images/marker-shadow.png
Binary file yt/gui/reason/html/resources/leaflet/images/marker-shadow.png has changed


diff -r 71ceede82775407793c71670ae2a5f063ff68aa4 -r fdc44a69a4814a753dd1b7e9a738a8f1c99bba33 yt/gui/reason/html/resources/leaflet/images/marker.png
Binary file yt/gui/reason/html/resources/leaflet/images/marker.png has changed


diff -r 71ceede82775407793c71670ae2a5f063ff68aa4 -r fdc44a69a4814a753dd1b7e9a738a8f1c99bba33 yt/gui/reason/html/resources/leaflet/images/popup-close.png
Binary file yt/gui/reason/html/resources/leaflet/images/popup-close.png has changed


diff -r 71ceede82775407793c71670ae2a5f063ff68aa4 -r fdc44a69a4814a753dd1b7e9a738a8f1c99bba33 yt/gui/reason/html/resources/leaflet/images/zoom-in.png
Binary file yt/gui/reason/html/resources/leaflet/images/zoom-in.png has changed


diff -r 71ceede82775407793c71670ae2a5f063ff68aa4 -r fdc44a69a4814a753dd1b7e9a738a8f1c99bba33 yt/gui/reason/html/resources/leaflet/images/zoom-out.png
Binary file yt/gui/reason/html/resources/leaflet/images/zoom-out.png has changed


diff -r 71ceede82775407793c71670ae2a5f063ff68aa4 -r fdc44a69a4814a753dd1b7e9a738a8f1c99bba33 yt/gui/reason/html/resources/leaflet/leaflet.css
--- a/yt/gui/reason/html/resources/leaflet/leaflet.css
+++ /dev/null
@@ -1,273 +0,0 @@
-/* required styles */
-
-.leaflet-map-pane,
-.leaflet-tile,
-.leaflet-marker-icon, 
-.leaflet-marker-shadow,
-.leaflet-tile-pane, 
-.leaflet-overlay-pane,
-.leaflet-shadow-pane,
-.leaflet-marker-pane,
-.leaflet-popup-pane,
-.leaflet-overlay-pane svg,
-.leaflet-zoom-box,
-.leaflet-image-layer { /* TODO optimize classes */ 
-	position: absolute;
-	}
-.leaflet-container {
-	overflow: hidden;
-	}
-.leaflet-tile-pane {
-	-webkit-transform: translate3d(0,0,0);
-	}
-.leaflet-tile, 
-.leaflet-marker-icon, 
-.leaflet-marker-shadow {
-	-moz-user-select: none;
-	-webkit-user-select: none;
-	user-select: none;
-	}
-.leaflet-marker-icon, 
-.leaflet-marker-shadow {
-	display: block;
-	}
-.leaflet-clickable {
-	cursor: pointer;
-	}
-.leaflet-container img {
-	max-width: auto;
-	}
-
-.leaflet-tile-pane { z-index: 2; }
-.leaflet-overlay-pane { z-index: 3; }
-.leaflet-shadow-pane { z-index: 4; }
-.leaflet-marker-pane { z-index: 5; }
-.leaflet-popup-pane { z-index: 6; }
-
-.leaflet-zoom-box {
-	width: 0;
-	height: 0;
-	}
-
-.leaflet-tile {
-	visibility: hidden;
-	}
-.leaflet-tile-loaded {
-	visibility: inherit;
-	}
-
-a.leaflet-active {
-	outline: 2px solid orange;
-	}
-
-
-/* Leaflet controls */
-
-.leaflet-control {
-	position: relative;
-	z-index: 7;
-	}
-.leaflet-top,
-.leaflet-bottom {
-	position: absolute;
-	}
-.leaflet-top {
-	top: 0;
-	}
-.leaflet-right {
-	right: 0;
-	}
-.leaflet-bottom {
-	bottom: 0;
-	}	
-.leaflet-left {
-	left: 0;
-	}
-.leaflet-control {
-	float: left;
-	clear: both;
-	}
-.leaflet-right .leaflet-control {
-	float: right;
-	}
-.leaflet-top .leaflet-control {
-	margin-top: 10px;
-	}
-.leaflet-bottom .leaflet-control {
-	margin-bottom: 10px;
-	}
-.leaflet-left .leaflet-control {
-	margin-left: 10px;
-	}
-.leaflet-right .leaflet-control {
-	margin-right: 10px;
-	}
-
-.leaflet-control-zoom {
-	padding: 5px;
-	background: rgba(0, 0, 0, 0.25);
-	
-	-moz-border-radius: 7px;
-	-webkit-border-radius: 7px;
-	border-radius: 7px;
-	}
-.leaflet-control-zoom a {
-	display: block;
-	width: 19px;
-	height: 19px;
-	background-position: 50% 50%;
-	background-repeat: no-repeat;
-	background-color: rgba(255, 255, 255, 0.75);
-	
-	-moz-border-radius: 4px;
-	-webkit-border-radius: 4px;
-	border-radius: 4px;
-	}
-.leaflet-control-zoom a:hover {
-	background-color: #fff;
-	}
-.leaflet-big-buttons .leaflet-control-zoom a {
-	width: 27px;
-	height: 27px;
-	}
-.leaflet-control-zoom-in {
-	background-image: url(images/zoom-in.png);
-	margin-bottom: 5px;
-	}
-.leaflet-control-zoom-out {
-	background-image: url(images/zoom-out.png);
-	}
-	
-.leaflet-container .leaflet-control-attribution {
-	margin: 0;
-	padding: 0 5px;
-	
-	font: 11px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
-	color: #333;
-	
-	background-color: rgba(255, 255, 255, 0.7);
-            
-	-moz-box-shadow: 0 0 7px #ccc;
-	-webkit-box-shadow: 0 0 7px #ccc;
-	box-shadow: 0 0 7px #ccc;
-	}
-
-
-/* Fade animations */
-
-.leaflet-fade-anim .leaflet-tile {
-	opacity: 0;
-	
-	-webkit-transition: opacity 0.2s linear;
-	-moz-transition: opacity 0.2s linear;
-	-o-transition: opacity 0.2s linear;
-	transition: opacity 0.2s linear;
-	}
-.leaflet-fade-anim .leaflet-tile-loaded {
-	opacity: 1;
-	}
-
-.leaflet-fade-anim .leaflet-popup {
-	opacity: 0;
-
-	-webkit-transition: opacity 0.2s linear;
-	-moz-transition: opacity 0.2s linear;
-	-o-transition: opacity 0.2s linear;
-	transition: opacity 0.2s linear;
-	}
-.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
-	opacity: 1;
-	}
-
-.leaflet-zoom-anim .leaflet-tile {
-	-webkit-transition: none;
-	-moz-transition: none;
-	-o-transition: none;
-	transition: none;
-	}
-
-.leaflet-zoom-anim .leaflet-objects-pane {
-	visibility: hidden;
-	}
-
-
-/* Popup layout */
-
-.leaflet-popup {
-	position: absolute;
-	text-align: center;
-	-webkit-transform: translate3d(0,0,0);
-	}
-.leaflet-popup-content-wrapper {
-	padding: 1px;
-	text-align: left;
-	}
-.leaflet-popup-content {
-	margin: 19px;
-	}
-.leaflet-popup-tip-container {
-	margin: 0 auto;
-	width: 40px;
-	height: 16px;
-	position: relative;
-	overflow: hidden;
-	}
-.leaflet-popup-tip {
-	width: 15px;
-	height: 15px;
-	padding: 1px;
-	
-	margin: -8px auto 0;
-	
-	-moz-transform: rotate(45deg);
-	-webkit-transform: rotate(45deg);
-	-ms-transform: rotate(45deg);
-	-o-transform: rotate(45deg);
-	transform: rotate(45deg);
-	}
-.leaflet-popup-close-button {
-	position: absolute;
-	top: 9px;
-	right: 9px;
-	
-	width: 10px;
-	height: 10px;
-	
-	overflow: hidden;
-	}
-.leaflet-popup-content p {
-	margin: 18px 0;
-	}
-
-
-/* Visual appearance */
-
-.leaflet-container {
-	background: #ddd;
-	}
-.leaflet-container a {
-	color: #0078A8;
-	}
-.leaflet-zoom-box {
-	border: 2px dotted #05f;
-	background: white;
-	opacity: 0.5;
-	}
-.leaflet-popup-content-wrapper, .leaflet-popup-tip {
-	background: white;
-	
-	box-shadow: 0 1px 10px #888;
-	-moz-box-shadow: 0 1px 10px #888;
-	 -webkit-box-shadow: 0 1px 14px #999;
-	}
-.leaflet-popup-content-wrapper {
-	-moz-border-radius: 20px; 
-	-webkit-border-radius: 20px;
-	border-radius: 20px;
-	}
-.leaflet-popup-content {
-	font: 12px/1.4 "Helvetica Neue", Arial, Helvetica, sans-serif;
-	}
-.leaflet-popup-close-button {
-	background: white url(images/popup-close.png);
-	}
\ No newline at end of file


diff -r 71ceede82775407793c71670ae2a5f063ff68aa4 -r fdc44a69a4814a753dd1b7e9a738a8f1c99bba33 yt/gui/reason/html/resources/leaflet/leaflet.ie.css
--- a/yt/gui/reason/html/resources/leaflet/leaflet.ie.css
+++ /dev/null
@@ -1,46 +0,0 @@
-.leaflet-tile {
-	filter: inherit;
-	}
-
-.leaflet-vml-shape {
-	width: 1px;
-	height: 1px;
-	}
-.lvml {
-	behavior: url(#default#VML); 
-	display: inline-block; 
-	position: absolute;
-	}
-	
-.leaflet-control {
-	display: inline;
-	}
-
-.leaflet-popup-tip {
-	width: 21px;
-	_width: 27px;
-	margin: 0 auto;
-	_margin-top: -3px;
-	
-	filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
-	-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
-	}
-.leaflet-popup-tip-container {
-	margin-top: -1px;
-	}
-.leaflet-popup-content-wrapper, .leaflet-popup-tip {
-	border: 1px solid #bbb;
-	}
-
-.leaflet-control-zoom {
-	filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#3F000000',EndColorStr='#3F000000');
-	}
-.leaflet-control-zoom a {
-	background-color: #eee;
-	}
-.leaflet-control-zoom a:hover {
-	background-color: #fff;
-	}
-.leaflet-control-attribution {
-	filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#B2FFFFFF,endColorstr=#B2FFFFFF);
-	}
\ No newline at end of file


diff -r 71ceede82775407793c71670ae2a5f063ff68aa4 -r fdc44a69a4814a753dd1b7e9a738a8f1c99bba33 yt/gui/reason/html/resources/leaflet/leaflet.js
--- a/yt/gui/reason/html/resources/leaflet/leaflet.js
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- Copyright (c) 2010-2011, CloudMade, Vladimir Agafonkin
- Leaflet is a BSD-licensed JavaScript library for map display and interaction.
- See http://cloudmade.github.com/Leaflet/ for more information.
-*/
-(function(a){var b={VERSION:"0.2",ROOT_URL:function(){for(var a=document.getElementsByTagName("script"),b=/^(.*\/)leaflet-?([\w-]*)\.js.*$/,e=0,f=a.length;e<f;e++){var g=a[e].src;if(g=g&&g.match(b)){if(g[2]=="include")break;return g[1]}}return"../../dist/"}(),noConflict:function(){a.L=this._originalL;return this},_originalL:a.L};window.L=b})(this);L.Util={extend:function(a){for(var b=Array.prototype.slice.call(arguments,1),c=0,d=b.length,e;c<d;c++){e=b[c]||{};for(var f in e)e.hasOwnProperty(f)&&(a[f]=e[f])}return a},bind:function(a,b){return function(){return a.apply(b,arguments)}},stamp:function(){var a=0;return function(b){b._leaflet_id=b._leaflet_id||++a;return b._leaflet_id}}(),requestAnimFrame:function(){function a(a){window.setTimeout(a,1E3/60)}var b=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||
-window.oRequestAnimationFrame||window.msRequestAnimationFrame||a;return function(c,d,e){c=d?L.Util.bind(c,d):d;e&&b===a?c():b(c)}}(),limitExecByInterval:function(a,b,c){function d(){e=!1;f&&(g.callee.apply(c,g),f=!1)}var e,f,g;return function(){g=arguments;e?f=!0:(e=!0,setTimeout(d,b),a.apply(c,g))}},falseFn:function(){return!1},formatNum:function(a,b){var c=Math.pow(10,b||5);return Math.round(a*c)/c},setOptions:function(a,b){a.options=L.Util.extend({},a.options,b)},getParamString:function(a){var b=
-[],c;for(c in a)a.hasOwnProperty(c)&&b.push(c+"="+a[c]);return"?"+b.join("&")}};L.Class=function(){};
-L.Class.extend=function(a){var b=function(){!L.Class._prototyping&&this.initialize&&this.initialize.apply(this,arguments)};L.Class._prototyping=!0;var c=new this;L.Class._prototyping=!1;c.constructor=b;b.prototype=c;c.superclass=this.prototype;a.statics&&(L.Util.extend(b,a.statics),delete a.statics);a.includes&&(L.Util.extend.apply(null,[c].concat(a.includes)),delete a.includes);if(a.options&&c.options)a.options=L.Util.extend({},c.options,a.options);L.Util.extend(c,a);b.extend=arguments.callee;b.include=
-function(a){L.Util.extend(this.prototype,a)};for(var d in this)this.hasOwnProperty(d)&&d!="prototype"&&(b[d]=this[d]);return b};L.Mixin={};
-L.Mixin.Events={addEventListener:function(a,b,c){var d=this._leaflet_events=this._leaflet_events||{};d[a]=d[a]||[];d[a].push({action:b,context:c});return this},hasEventListeners:function(a){return"_leaflet_events"in this&&a in this._leaflet_events&&this._leaflet_events[a].length>0},removeEventListener:function(a,b,c){if(!this.hasEventListeners(a))return this;for(var d=0,e=this._leaflet_events,f=e[a].length;d<f;d++)if(e[a][d].action===b&&(!c||e[a][d].context===c)){e[a].splice(d,1);break}return this},fireEvent:function(a,
-b){if(this.hasEventListeners(a)){for(var c=L.Util.extend({type:a,target:this},b),d=this._leaflet_events[a].slice(),e=0,f=d.length;e<f;e++)d[e].action.call(d[e].context||this,c);return this}}};L.Mixin.Events.on=L.Mixin.Events.addEventListener;L.Mixin.Events.off=L.Mixin.Events.removeEventListener;L.Mixin.Events.fire=L.Mixin.Events.fireEvent;(function(){var a=navigator.userAgent.toLowerCase(),b=!!window.ActiveXObject,c=a.indexOf("webkit")!=-1,d=a.indexOf("mobi")!=-1,e=a.indexOf("android")!=-1,f=window.opera;L.Browser={ie:b,ie6:b&&!window.XMLHttpRequest,webkit:c,webkit3d:c&&"WebKitCSSMatrix"in window&&"m11"in new WebKitCSSMatrix,mobileWebkit:c&&(d||e),mobileOpera:d&&f,gecko:a.indexOf("gecko")!=-1,android:e};L.Browser.touch=L.Browser.mobileWebkit||L.Browser.mobileOpera})();L.Point=function(a,b,c){this.x=c?Math.round(a):a;this.y=c?Math.round(b):b};
-L.Point.prototype={add:function(a){return this.clone()._add(a)},_add:function(a){this.x+=a.x;this.y+=a.y;return this},subtract:function(a){return this.clone()._subtract(a)},_subtract:function(a){this.x-=a.x;this.y-=a.y;return this},divideBy:function(a,b){return new L.Point(this.x/a,this.y/a,b)},multiplyBy:function(a){return new L.Point(this.x*a,this.y*a)},distanceTo:function(a){var b=a.x-this.x,a=a.y-this.y;return Math.sqrt(b*b+a*a)},round:function(){return this.clone()._round()},_round:function(){this.x=
-Math.round(this.x);this.y=Math.round(this.y);return this},clone:function(){return new L.Point(this.x,this.y)},toString:function(){return"Point("+L.Util.formatNum(this.x)+", "+L.Util.formatNum(this.y)+")"}};L.Bounds=L.Class.extend({initialize:function(a,b){if(a)for(var c=a instanceof Array?a:[a,b],d=0,e=c.length;d<e;d++)this.extend(c[d])},extend:function(a){!this.min&&!this.max?(this.min=new L.Point(a.x,a.y),this.max=new L.Point(a.x,a.y)):(this.min.x=Math.min(a.x,this.min.x),this.max.x=Math.max(a.x,this.max.x),this.min.y=Math.min(a.y,this.min.y),this.max.y=Math.max(a.y,this.max.y))},getCenter:function(a){return new L.Point((this.min.x+this.max.x)/2,(this.min.y+this.max.y)/2,a)},contains:function(a){var b;
-if(a instanceof L.Bounds)b=a.min,a=a.max;return b.x>=this.min.x&&a.x<=this.max.x&&b.y>=this.min.y&&a.y<=this.max.y}});L.Transformation=L.Class.extend({initialize:function(a,b,c,d){this._a=a;this._b=b;this._c=c;this._d=d},transform:function(a,b){return this._transform(a.clone(),b)},_transform:function(a,b){b=b||1;a.x=b*(this._a*a.x+this._b);a.y=b*(this._c*a.y+this._d);return a},untransform:function(a,b){b=b||1;return new L.Point((a.x/b-this._b)/this._a,(a.y/b-this._d)/this._c)}});L.LineUtil={simplify:function(a,b){if(!b)return a.slice();a=this.reducePoints(a,b);return a=this.simplifyDP(a,b)},pointToSegmentDistance:function(a,b,c){return Math.sqrt(this._sqPointToSegmentDist(a,b,c))},simplifyDP:function(a,b){for(var c=0,d=0,e=b*b,f=1,g=a.length,h;f<g-1;f++)h=this._sqPointToSegmentDist(a[f],a[0],a[g-1]),h>c&&(d=f,c=h);return c>=e?(c=a.slice(0,d),d=a.slice(d),g=this.simplifyDP(c,b).slice(0,g-2),d=this.simplifyDP(d,b),g.concat(d)):[a[0],a[g-1]]},reducePoints:function(a,b){for(var c=
-[a[0]],d=b*b,e=1,f=0,g=a.length;e<g;e++)this._sqDist(a[e],a[f])<d||(c.push(a[e]),f=e);f<g-1&&c.push(a[g-1]);return c},clipSegment:function(a,b,c,d){var d=d?this._lastCode:this._getBitCode(a,c),e=this._getBitCode(b,c);for(this._lastCode=e;;)if(d|e)if(d&e)return!1;else{var f=d||e,g=this._getEdgeIntersection(a,b,f,c),h=this._getBitCode(g,c);f==d?(a=g,d=h):(b=g,e=h)}else return[a,b]},_getEdgeIntersection:function(a,b,c,d){var e=b.x-a.x,b=b.y-a.y,f=d.min,d=d.max;if(c&8)return new L.Point(a.x+e*(d.y-a.y)/
-b,d.y);else if(c&4)return new L.Point(a.x+e*(f.y-a.y)/b,f.y);else if(c&2)return new L.Point(d.x,a.y+b*(d.x-a.x)/e);else if(c&1)return new L.Point(f.x,a.y+b*(f.x-a.x)/e)},_getBitCode:function(a,b){var c=0;a.x<b.min.x?c|=1:a.x>b.max.x&&(c|=2);a.y<b.min.y?c|=4:a.y>b.max.y&&(c|=8);return c},_sqDist:function(a,b){var c=b.x-a.x,d=b.y-a.y;return c*c+d*d},_sqPointToSegmentDist:function(a,b,c){var d=c.x-b.x,e=c.y-b.y;if(!d&&!e)return this._sqDist(a,b);var f=((a.x-b.x)*d+(a.y-b.y)*e)/this._sqDist(b,c);if(f<
-0)return this._sqDist(a,b);if(f>1)return this._sqDist(a,c);b=new L.Point(b.x+d*f,b.y+e*f);return this._sqDist(a,b)}};L.PolyUtil={};L.PolyUtil.clipPolygon=function(a,b){var c,d=[1,4,2,8],e,f,g,h,j,k,l=L.LineUtil;e=0;for(j=a.length;e<j;e++)a[e]._code=l._getBitCode(a[e],b);for(g=0;g<4;g++){k=d[g];c=[];e=0;j=a.length;for(f=j-1;e<j;f=e++)if(h=a[e],f=a[f],h._code&k){if(!(f._code&k))f=l._getEdgeIntersection(f,h,k,b),f._code=l._getBitCode(f,b),c.push(f)}else{if(f._code&k)f=l._getEdgeIntersection(f,h,k,b),f._code=l._getBitCode(f,b),c.push(f);c.push(h)}a=c}return a};L.DomEvent={addListener:function(a,b,c,d){function e(b){return c.call(d||a,b||L.DomEvent._getEvent())}var f=L.Util.stamp(c);if(L.Browser.touch&&b=="dblclick"&&this.addDoubleTapListener)this.addDoubleTapListener(a,e,f);else if("addEventListener"in a)if(b=="mousewheel")a.addEventListener("DOMMouseScroll",e,!1),a.addEventListener(b,e,!1);else if(b=="mouseenter"||b=="mouseleave"){var g=e,e=function(b){if(L.DomEvent._checkMouse(a,b))return g(b)};a.addEventListener(b=="mouseenter"?"mouseover":"mouseout",
-e,!1)}else a.addEventListener(b,e,!1);else"attachEvent"in a&&a.attachEvent("on"+b,e);a["_leaflet_"+b+f]=e},removeListener:function(a,b,c){var c=L.Util.stamp(c),d="_leaflet_"+b+c;handler=a[d];L.Browser.mobileWebkit&&b=="dblclick"&&this.removeDoubleTapListener?this.removeDoubleTapListener(a,c):"removeEventListener"in a?b=="mousewheel"?(a.removeEventListener("DOMMouseScroll",handler,!1),a.removeEventListener(b,handler,!1)):b=="mouseenter"||b=="mouseleave"?a.removeEventListener(b=="mouseenter"?"mouseover":
-"mouseout",handler,!1):a.removeEventListener(b,handler,!1):"detachEvent"in a&&a.detachEvent("on"+b,handler);a[d]=null},_checkMouse:function(a,b){var c=b.relatedTarget;if(!c)return!0;try{for(;c&&c!=a;)c=c.parentNode}catch(d){return!1}return c!=a},_getEvent:function(){var a=window.event;if(!a)for(var b=arguments.callee.caller;b;){if((a=b.arguments[0])&&Event==a.constructor)break;b=b.caller}return a},stopPropagation:function(a){a.stopPropagation?a.stopPropagation():a.cancelBubble=!0},disableClickPropagation:function(a){L.DomEvent.addListener(a,
-"mousedown",L.DomEvent.stopPropagation);L.DomEvent.addListener(a,"click",L.DomEvent.stopPropagation);L.DomEvent.addListener(a,"dblclick",L.DomEvent.stopPropagation)},preventDefault:function(a){a.preventDefault?a.preventDefault():a.returnValue=!1},stop:function(a){L.DomEvent.preventDefault(a);L.DomEvent.stopPropagation(a)},getMousePosition:function(a,b){var c=new L.Point(a.pageX?a.pageX:a.clientX+document.body.scrollLeft+document.documentElement.scrollLeft,a.pageY?a.pageY:a.clientY+document.body.scrollTop+
-document.documentElement.scrollTop);return b?c.subtract(L.DomUtil.getCumulativeOffset(b)):c},getWheelDelta:function(a){var b=0;a.wheelDelta&&(b=a.wheelDelta/120);a.detail&&(b=-a.detail/3);return b}};L.Util.extend(L.DomEvent,{addDoubleTapListener:function(a,b,c){function d(a){if(a.touches.length==1){var b=Date.now(),c=b-(f||b);j=a.touches[0];g=c>0&&c<=h;f=b}}function e(){if(g)j.type="dblclick",b(j),f=null}var f,g=!1,h=250,j;a["_leaflet_touchstart"+c]=d;a["_leaflet_touchend"+c]=e;a.addEventListener("touchstart",d,!1);a.addEventListener("touchend",e,!1)},removeDoubleTapListener:function(a,b){a.removeEventListener(a,a["_leaflet_touchstart"+b],!1);a.removeEventListener(a,a["_leaflet_touchend"+b],
-!1)}});L.DomUtil={get:function(a){return typeof a=="string"?document.getElementById(a):a},getStyle:function(a,b){var c=a.style[b];!c&&a.currentStyle&&(c=a.currentStyle[b]);if(!c||c=="auto")c=(c=document.defaultView.getComputedStyle(a,null))?c[b]:null;return c=="auto"?null:c},getCumulativeOffset:function(a){var b=0,c=0;do b+=a.offsetTop||0,c+=a.offsetLeft||0,a=a.offsetParent;while(a);return new L.Point(c,b)},create:function(a,b,c){a=document.createElement(a);a.className=b;c&&c.appendChild(a);return a},disableTextSelection:function(){document.selection&&
-document.selection.empty&&document.selection.empty();if(!this._onselectstart)this._onselectstart=document.onselectstart,document.onselectstart=L.Util.falseFn},enableTextSelection:function(){document.onselectstart=this._onselectstart;this._onselectstart=null},CLASS_RE:/(\\s|^)'+cls+'(\\s|$)/,hasClass:function(a,b){return a.className.length>0&&RegExp("(^|\\s)"+b+"(\\s|$)").test(a.className)},addClass:function(a,b){L.DomUtil.hasClass(a,b)||(a.className+=(a.className?" ":"")+b)},setOpacity:function(a,
-b){L.Browser.ie?a.style.filter="alpha(opacity="+Math.round(b*100)+")":a.style.opacity=b},testProp:function(a){for(var b=document.documentElement.style,c=0;c<a.length;c++)if(a[c]in b)return a[c];return!1},getTranslateString:function(a){return L.DomUtil.TRANSLATE_OPEN+a.x+"px,"+a.y+"px"+L.DomUtil.TRANSLATE_CLOSE},getScaleString:function(a,b){return L.DomUtil.getTranslateString(b)+" scale("+a+") "+L.DomUtil.getTranslateString(b.multiplyBy(-1))},setPosition:function(a,b){a._leaflet_pos=b;L.Browser.webkit?
-a.style[L.DomUtil.TRANSFORM]=L.DomUtil.getTranslateString(b):(a.style.left=b.x+"px",a.style.top=b.y+"px")},getPosition:function(a){return a._leaflet_pos}};
-L.Util.extend(L.DomUtil,{TRANSITION:L.DomUtil.testProp(["transition","webkitTransition","OTransition","MozTransition","msTransition"]),TRANSFORM:L.DomUtil.testProp(["transformProperty","WebkitTransform","OTransform","MozTransform","msTransform"]),TRANSLATE_OPEN:"translate"+(L.Browser.webkit3d?"3d(":"("),TRANSLATE_CLOSE:L.Browser.webkit3d?",0)":")"});L.Draggable=L.Class.extend({includes:L.Mixin.Events,statics:{START:L.Browser.touch?"touchstart":"mousedown",END:L.Browser.touch?"touchend":"mouseup",MOVE:L.Browser.touch?"touchmove":"mousemove",TAP_TOLERANCE:15},initialize:function(a,b){this._element=a;this._dragStartTarget=b||a},enable:function(){if(!this._enabled)L.DomEvent.addListener(this._dragStartTarget,L.Draggable.START,this._onDown,this),this._enabled=!0},disable:function(){if(this._enabled)L.DomEvent.removeListener(this._dragStartTarget,
-L.Draggable.START,this._onDown),this._enabled=!1},_onDown:function(a){if(!(a.shiftKey||a.which!=1&&a.button!=1&&!a.touches)&&!(a.touches&&a.touches.length>1)){var b=a.touches&&a.touches.length==1?a.touches[0]:a;L.DomEvent.preventDefault(a);L.Browser.mobileWebkit&&(b.target.className+=" leaflet-active");this._moved=!1;L.DomUtil.disableTextSelection();this._setMovingCursor();this._startPos=this._newPos=L.DomUtil.getPosition(this._element);this._startPoint=new L.Point(b.clientX,b.clientY);L.DomEvent.addListener(document,
-L.Draggable.MOVE,this._onMove,this);L.DomEvent.addListener(document,L.Draggable.END,this._onUp,this)}},_onMove:function(a){if(!(a.touches&&a.touches.length>1)){L.DomEvent.preventDefault(a);a=a.touches&&a.touches.length==1?a.touches[0]:a;if(!this._moved)this.fire("dragstart"),this._moved=!0;this._newPos=this._startPos.add(new L.Point(a.clientX,a.clientY)).subtract(this._startPoint);L.Util.requestAnimFrame(this._updatePosition,this,!0);this.fire("drag")}},_updatePosition:function(){L.DomUtil.setPosition(this._element,
-this._newPos)},_onUp:function(a){if(a.changedTouches){var a=a.changedTouches[0],b=a.target,c=this._newPos&&this._newPos.distanceTo(this._startPos)||0;b.className=b.className.replace(" leaflet-active","");c<L.Draggable.TAP_TOLERANCE&&this._simulateEvent("click",a)}L.DomUtil.enableTextSelection();this._restoreCursor();L.DomEvent.removeListener(document,L.Draggable.MOVE,this._onMove);L.DomEvent.removeListener(document,L.Draggable.END,this._onUp);this._moved&&this.fire("dragend")},_removeActiveClass:function(){},
-_setMovingCursor:function(){this._bodyCursor=document.body.style.cursor;document.body.style.cursor="move"},_restoreCursor:function(){document.body.style.cursor=this._bodyCursor},_simulateEvent:function(a,b){var c=document.createEvent("MouseEvent");c.initMouseEvent(a,!0,!0,window,1,b.screenX,b.screenY,b.clientX,b.clientY,!1,!1,!1,!1,0,null);b.target.dispatchEvent(c)}});L.Transition=L.Class.extend({includes:L.Mixin.Events,statics:{CUSTOM_PROPS_SETTERS:{position:L.DomUtil.setPosition},implemented:function(){return L.Transition.NATIVE||L.Transition.TIMER}},options:{easing:"ease",duration:0.5},_setProperty:function(a,b){var c=L.Transition.CUSTOM_PROPS_SETTERS;if(a in c)c[a](this._el,b);else this._el.style[a]=b}});L.Transition=L.Transition.extend({statics:function(){var a=L.DomUtil.TRANSITION;return{NATIVE:!!a,TRANSITION:a,PROPERTY:a+"Property",DURATION:a+"Duration",EASING:a+"TimingFunction",END:a=="webkitTransition"||a=="OTransition"?a+"End":"transitionend",CUSTOM_PROPS_PROPERTIES:{position:L.Browser.webkit?L.DomUtil.TRANSFORM:"top, left"}}}(),options:{fakeStepInterval:100},initialize:function(a,b){this._el=a;L.Util.setOptions(this,b);L.DomEvent.addListener(a,L.Transition.END,this._onTransitionEnd,this);this._onFakeStep=
-L.Util.bind(this._onFakeStep,this)},run:function(a){var b,c=[],d=L.Transition.CUSTOM_PROPS_PROPERTIES;for(b in a)a.hasOwnProperty(b)&&(b=d[b]?d[b]:b,b=b.replace(/([A-Z])/g,function(a){return"-"+a.toLowerCase()}),c.push(b));this._el.style[L.Transition.DURATION]=this.options.duration+"s";this._el.style[L.Transition.EASING]=this.options.easing;this._el.style[L.Transition.PROPERTY]=c.join(", ");for(b in a)a.hasOwnProperty(b)&&this._setProperty(b,a[b]);this._inProgress=!0;this.fire("start");L.Transition.NATIVE?
-this._timer=setInterval(this._onFakeStep,this.options.fakeStepInterval):this._onTransitionEnd()},_onFakeStep:function(){this.fire("step")},_onTransitionEnd:function(){if(this._inProgress)this._inProgress=!1,clearInterval(this._timer),this._el.style[L.Transition.PROPERTY]="none",this.fire("step"),this.fire("end")}});L.Transition=L.Transition.NATIVE?L.Transition:L.Transition.extend({statics:{getTime:Date.now||function(){return+new Date},TIMER:!0,EASINGS:{ease:[0.25,0.1,0.25,1],linear:[0,0,1,1],"ease-in":[0.42,0,1,1],"ease-out":[0,0,0.58,1],"ease-in-out":[0.42,0,0.58,1]},CUSTOM_PROPS_GETTERS:{position:L.DomUtil.getPosition},UNIT_RE:/^[\d\.]+(\D*)$/},options:{fps:50},initialize:function(a,b){this._el=a;L.Util.extend(this.options,b);var c=L.Transition.EASINGS[this.options.easing]||L.Transition.EASINGS.ease;this._p1=
-new L.Point(0,0);this._p2=new L.Point(c[0],c[1]);this._p3=new L.Point(c[2],c[3]);this._p4=new L.Point(1,1);this._step=L.Util.bind(this._step,this);this._interval=Math.round(1E3/this.options.fps)},run:function(a){this._props={};var b=L.Transition.CUSTOM_PROPS_GETTERS,c=L.Transition.UNIT_RE;this.fire("start");for(var d in a)if(a.hasOwnProperty(d)){var e={};if(d in b)e.from=b[d](this._el);else{var f=this._el.style[d].match(c);e.from=parseFloat(f[0]);e.unit=f[1]}e.to=a[d];this._props[d]=e}clearInterval(this._timer);
-this._timer=setInterval(this._step,this._interval);this._startTime=L.Transition.getTime()},_step:function(){var a=L.Transition.getTime()-this._startTime,b=this.options.duration*1E3;a<b?this._runFrame(this._cubicBezier(a/b)):(this._runFrame(1),this._complete())},_runFrame:function(a){var b=L.Transition.CUSTOM_PROPS_SETTERS,c,d;for(c in this._props)this._props.hasOwnProperty(c)&&(d=this._props[c],c in b?(d=d.to.subtract(d.from).multiplyBy(a).add(d.from),b[c](this._el,d)):this._el.style[c]=(d.to-d.from)*
-a+d.from+d.unit);this.fire("step")},_complete:function(){clearInterval(this._timer);this.fire("end")},_cubicBezier:function(a){var b=3*Math.pow(1-a,2)*a,c=3*(1-a)*Math.pow(a,2),d=Math.pow(a,3),a=this._p1.multiplyBy(Math.pow(1-a,3)),b=this._p2.multiplyBy(b),c=this._p3.multiplyBy(c),d=this._p4.multiplyBy(d);return a.add(b).add(c).add(d).y}});L.LatLng=function(a,b,c){c!==!0&&(a=Math.max(Math.min(a,90),-90),b=(b+180)%360+(b<-180?180:-180));this.lat=a;this.lng=b};L.Util.extend(L.LatLng,{DEG_TO_RAD:Math.PI/180,RAD_TO_DEG:180/Math.PI,MAX_MARGIN:1.0E-9});L.LatLng.prototype={equals:function(a){if(!(a instanceof L.LatLng))return!1;return Math.max(Math.abs(this.lat-a.lat),Math.abs(this.lng-a.lng))<=L.LatLng.MAX_MARGIN},toString:function(){return"LatLng("+L.Util.formatNum(this.lat)+", "+L.Util.formatNum(this.lng)+")"}};L.LatLngBounds=L.Class.extend({initialize:function(a,b){if(a)for(var c=a instanceof Array?a:[a,b],d=0,e=c.length;d<e;d++)this.extend(c[d])},extend:function(a){!this._southWest&&!this._northEast?(this._southWest=new L.LatLng(a.lat,a.lng),this._northEast=new L.LatLng(a.lat,a.lng)):(this._southWest.lat=Math.min(a.lat,this._southWest.lat),this._southWest.lng=Math.min(a.lng,this._southWest.lng),this._northEast.lat=Math.max(a.lat,this._northEast.lat),this._northEast.lng=Math.max(a.lng,this._northEast.lng))},
-getCenter:function(){return new L.LatLng((this._southWest.lat+this._northEast.lat)/2,(this._southWest.lng+this._northEast.lng)/2)},getSouthWest:function(){return this._southWest},getNorthEast:function(){return this._northEast},getNorthWest:function(){return new L.LatLng(this._northEast.lat,this._southWest.lng)},getSouthEast:function(){return new L.LatLng(this._southWest.lat,this._northEast.lng)},contains:function(a){var b=this._southWest,c=this._northEast,d;a instanceof L.LatLngBounds?(d=a.getSouthWest(),
-a=a.getNorthEast()):d=a;return d.lat>=b.lat&&a.lat<=c.lat&&d.lng>=b.lng&&a.lng<=c.lng}});L.Projection={};L.Projection.SphericalMercator={MAX_LATITUDE:85.0511287798,project:function(a){var b=L.LatLng.DEG_TO_RAD,c=this.MAX_LATITUDE,d=a.lng*b,a=Math.max(Math.min(c,a.lat),-c)*b,a=Math.log(Math.tan(Math.PI/4+a/2));return new L.Point(d,a)},unproject:function(a,b){var c=L.LatLng.RAD_TO_DEG;return new L.LatLng((2*Math.atan(Math.exp(a.y))-Math.PI/2)*c,a.x*c,b)}};L.Projection.LonLat={project:function(a){return new L.Point(a.lng,a.lat)},unproject:function(a,b){return new L.LatLng(a.y,a.x,b)}};L.Projection.Mercator={MAX_LATITUDE:85.0840591556,R_MINOR:6356752.3142,R_MAJOR:6378137,project:function(a){var b=L.LatLng.DEG_TO_RAD,c=this.MAX_LATITUDE,d=this.R_MAJOR,e=a.lng*b*d,a=Math.max(Math.min(c,a.lat),-c)*b,b=this.R_MINOR/d,b=Math.sqrt(1-b*b),c=b*Math.sin(a),c=Math.pow((1-c)/(1+c),b*0.5),a=-d*Math.log(Math.tan(0.5*(Math.PI*0.5-a))/c);return new L.Point(e,a)},unproject:function(a,b){for(var c=L.LatLng.RAD_TO_DEG,d=this.R_MAJOR,e=a.x*c/d,f=this.R_MINOR/d,f=Math.sqrt(1-f*f),d=Math.exp(-a.y/d),
-g=Math.PI/2-2*Math.atan(d),h=15,j=0.1;Math.abs(j)>1.0E-7&&--h>0;)j=f*Math.sin(g),j=Math.PI/2-2*Math.atan(d*Math.pow((1-j)/(1+j),0.5*f))-g,g+=j;return new L.LatLng(g*c,e,b)}};L.CRS={latLngToPoint:function(a,b){return this.transformation._transform(this.projection.project(a),b)},pointToLatLng:function(a,b,c){return this.projection.unproject(this.transformation.untransform(a,b),c)},project:function(a){return this.projection.project(a)}};L.CRS.EPSG3857=L.Util.extend({},L.CRS,{code:"EPSG:3857",projection:L.Projection.SphericalMercator,transformation:new L.Transformation(0.5/Math.PI,0.5,-0.5/Math.PI,0.5),project:function(a){return this.projection.project(a).multiplyBy(6378137)}});L.CRS.EPSG900913=L.Util.extend({},L.CRS.EPSG3857,{code:"EPSG:900913"});L.CRS.EPSG4326=L.Util.extend({},L.CRS,{code:"EPSG:4326",projection:L.Projection.LonLat,transformation:new L.Transformation(1/360,0.5,-1/360,0.5)});L.CRS.EPSG3395=L.Util.extend({},L.CRS,{code:"EPSG:3395",projection:L.Projection.Mercator,transformation:function(){var a=L.Projection.Mercator;return new L.Transformation(0.5/(Math.PI*a.R_MAJOR),0.5,-0.5/(Math.PI*a.R_MINOR),0.5)}()});L.LayerGroup=L.Class.extend({initialize:function(a){this._layers={};if(a)for(var b=0,c=a.length;b<c;b++)this.addLayer(a[b])},addLayer:function(a){this._layers[L.Util.stamp(a)]=a;this._map&&this._map.addLayer(a);return this},removeLayer:function(a){delete this._layers[L.Util.stamp(a)];this._map&&this._map.removeLayer(a);return this},clearLayers:function(){this._iterateLayers(this.removeLayer,this);return this},onAdd:function(a){this._map=a;this._iterateLayers(a.addLayer,a)},onRemove:function(a){this._iterateLayers(a.removeLayer,
-a);delete this._map},_iterateLayers:function(a,b){for(var c in this._layers)this._layers.hasOwnProperty(c)&&a.call(b,this._layers[c])}});L.FeatureGroup=L.LayerGroup.extend({includes:L.Mixin.Events,addLayer:function(a){this._initEvents(a);L.LayerGroup.prototype.addLayer.call(this,a);this._popupContent&&a.bindPopup&&a.bindPopup(this._popupContent)},bindPopup:function(a){this._popupContent=a;for(var b in this._layers)this._layers.hasOwnProperty(b)&&this._layers[b].bindPopup&&this._layers[b].bindPopup(a)},_events:["click","dblclick","mouseover","mouseout"],_initEvents:function(a){for(var b=0,c=this._events.length;b<c;b++)a.on(this._events[b],
-this._propagateEvent,this)},_propagateEvent:function(a){a.layer=a.target;a.target=this;this.fire(a.type,a)}});L.TileLayer=L.Class.extend({includes:L.Mixin.Events,options:{minZoom:0,maxZoom:18,tileSize:256,subdomains:"abc",errorTileUrl:"",attribution:"",opacity:1,scheme:"xyz",noWrap:!1,unloadInvisibleTiles:L.Browser.mobileWebkit,updateWhenIdle:L.Browser.mobileWebkit},initialize:function(a,b){L.Util.setOptions(this,b);this._url=a;if(typeof this.options.subdomains=="string")this.options.subdomains=this.options.subdomains.split("")},onAdd:function(a){this._map=a;this._initContainer();this._createTileProto();
-a.on("viewreset",this._reset,this);if(this.options.updateWhenIdle)a.on("moveend",this._update,this);else this._limitedUpdate=L.Util.limitExecByInterval(this._update,100,this),a.on("move",this._limitedUpdate,this);this._reset();this._update()},onRemove:function(){this._map.getPanes().tilePane.removeChild(this._container);this._container=null;this._map.off("viewreset",this._reset,this);this.options.updateWhenIdle?this._map.off("moveend",this._update,this):this._map.off("move",this._limitedUpdate,this)},
-getAttribution:function(){return this.options.attribution},setOpacity:function(a){this.options.opacity=a;this._setOpacity(a);if(L.Browser.webkit)for(i in this._tiles)this._tiles[i].style.webkitTransform+=" translate(0,0)"},_setOpacity:function(a){a<1&&L.DomUtil.setOpacity(this._container,a)},_initContainer:function(){var a=this._map.getPanes().tilePane;if(!this._container||a.empty)this._container=L.DomUtil.create("div","leaflet-layer",a),this._setOpacity(this.options.opacity)},_reset:function(){this._tiles=
-{};this._initContainer();this._container.innerHTML=""},_update:function(){var a=this._map.getPixelBounds(),b=this.options.tileSize,c=new L.Point(Math.floor(a.min.x/b),Math.floor(a.min.y/b)),a=new L.Point(Math.floor(a.max.x/b),Math.floor(a.max.y/b)),c=new L.Bounds(c,a);this._addTilesFromCenterOut(c);this.options.unloadInvisibleTiles&&this._removeOtherTiles(c)},_addTilesFromCenterOut:function(a){for(var b=[],c=a.getCenter(),d=a.min.y;d<=a.max.y;d++)for(var e=a.min.x;e<=a.max.x;e++)e+":"+d in this._tiles||
-b.push(new L.Point(e,d));b.sort(function(a,b){return a.distanceTo(c)-b.distanceTo(c)});this._tilesToLoad=b.length;a=0;for(d=this._tilesToLoad;a<d;a++)this._addTile(b[a])},_removeOtherTiles:function(a){var b,c,d;for(d in this._tiles)if(this._tiles.hasOwnProperty(d)&&(b=d.split(":"),c=parseInt(b[0],10),b=parseInt(b[1],10),c<a.min.x||c>a.max.x||b<a.min.y||b>a.max.y))this._tiles[d].src="",this._tiles[d].parentNode==this._container&&this._container.removeChild(this._tiles[d]),delete this._tiles[d]},_addTile:function(a){var b=
-this._getTilePos(a),c=this._map.getZoom(),d=a.x+":"+a.y,e=1<<c;if(!this.options.noWrap)a.x=(a.x%e+e)%e;if(!(a.y<0||a.y>=e)){var f=this._createTile();L.DomUtil.setPosition(f,b);this._tiles[d]=f;if(this.options.scheme=="tms")a.y=e-a.y-1;this._loadTile(f,a,c);this._container.appendChild(f)}},_getTilePos:function(a){var b=this._map.getPixelOrigin();return a.multiplyBy(this.options.tileSize).subtract(b)},getTileUrl:function(a,b){return this._url.replace("{s}",this.options.subdomains[(a.x+a.y)%this.options.subdomains.length]).replace("{z}",
-b).replace("{x}",a.x).replace("{y}",a.y)},_createTileProto:function(){this._tileImg=L.DomUtil.create("img","leaflet-tile");this._tileImg.galleryimg="no";var a=this.options.tileSize;this._tileImg.style.width=a+"px";this._tileImg.style.height=a+"px"},_createTile:function(){var a=this._tileImg.cloneNode(!1);a.onselectstart=a.onmousemove=L.Util.falseFn;return a},_loadTile:function(a,b,c){a._layer=this;a.onload=this._tileOnLoad;a.onerror=this._tileOnError;a.src=this.getTileUrl(b,c)},_tileOnLoad:function(){var a=
-this._layer;this.className+=" leaflet-tile-loaded";a.fire("tileload",{tile:this,url:this.src});a._tilesToLoad--;a._tilesToLoad||a.fire("load")},_tileOnError:function(){var a=this._layer;a.fire("tileerror",{tile:this,url:this.src});if(a=a.options.errorTileUrl)this.src=a}});L.TileLayer.WMS=L.TileLayer.extend({defaultWmsParams:{service:"WMS",request:"GetMap",version:"1.1.1",layers:"",styles:"",format:"image/jpeg",transparent:!1},initialize:function(a,b){this._url=a;this.wmsParams=L.Util.extend({},this.defaultWmsParams);this.wmsParams.width=this.wmsParams.height=this.options.tileSize;for(var c in b)this.options.hasOwnProperty(c)||(this.wmsParams[c]=b[c]);L.Util.setOptions(this,b)},onAdd:function(a){this.wmsParams[parseFloat(this.wmsParams.version)>=1.3?"crs":"srs"]=a.options.crs.code;
-L.TileLayer.prototype.onAdd.call(this,a)},getTileUrl:function(a){var b=this.options.tileSize,a=a.multiplyBy(b),b=a.add(new L.Point(b,b)),a=this._map.unproject(a,this._zoom,!0),b=this._map.unproject(b,this._zoom,!0),a=this._map.options.crs.project(a),b=this._map.options.crs.project(b),b=[a.x,b.y,b.x,a.y].join(",");return this._url+L.Util.getParamString(this.wmsParams)+"&bbox="+b}});L.TileLayer.Canvas=L.TileLayer.extend({options:{async:!1},initialize:function(a){L.Util.setOptions(this,a)},_createTileProto:function(){this._canvasProto=L.DomUtil.create("canvas","leaflet-tile");var a=this.options.tileSize;this._canvasProto.width=a;this._canvasProto.height=a},_createTile:function(){var a=this._canvasProto.cloneNode(!1);a.onselectstart=a.onmousemove=L.Util.falseFn;return a},_loadTile:function(a,b,c){a._layer=this;this.drawTile(a,b,c);this.options.async||this.tileDrawn(a)},drawTile:function(){},
-tileDrawn:function(a){this._tileOnLoad.call(a)}});L.ImageOverlay=L.Class.extend({includes:L.Mixin.Events,initialize:function(a,b){this._url=a;this._bounds=b},onAdd:function(a){this._map=a;this._image||this._initImage();a.getPanes().overlayPane.appendChild(this._image);a.on("viewreset",this._reset,this);this._reset()},onRemove:function(a){a.getPanes().overlayPane.removeChild(this._image);a.off("viewreset",this._reset,this)},_initImage:function(){this._image=L.DomUtil.create("img","leaflet-image-layer");this._image.style.visibility="hidden";L.Util.extend(this._image,
-{galleryimg:"no",onselectstart:L.Util.falseFn,onmousemove:L.Util.falseFn,onload:this._onImageLoad,src:this._url})},_reset:function(){var a=this._map.latLngToLayerPoint(this._bounds.getNorthWest()),b=this._map.latLngToLayerPoint(this._bounds.getSouthEast()).subtract(a);L.DomUtil.setPosition(this._image,a);this._image.style.width=b.x+"px";this._image.style.height=b.y+"px"},_onImageLoad:function(){this.style.visibility=""}});L.Popup=L.Class.extend({includes:L.Mixin.Events,options:{maxWidth:300,autoPan:!0,closeButton:!0,offset:new L.Point(0,2),autoPanPadding:new L.Point(5,5)},initialize:function(a){L.Util.setOptions(this,a)},onAdd:function(a){this._map=a;this._container||this._initLayout();this._updateContent();this._container.style.opacity="0";this._map._panes.popupPane.appendChild(this._container);this._map.on("viewreset",this._updatePosition,this);if(this._map.options.closePopupOnClick)this._map.on("preclick",this._close,
-this);this._update();this._container.style.opacity="1";this._opened=!0},onRemove:function(a){a._panes.popupPane.removeChild(this._container);a.off("viewreset",this._updatePosition,this);a.off("click",this._close,this);this._container.style.opacity="0";this._opened=!1},setLatLng:function(a){this._latlng=a;this._opened&&this._update();return this},setContent:function(a){this._content=a;this._opened&&this._update();return this},_close:function(){this._opened&&this._map.removeLayer(this)},_initLayout:function(){this._container=
-L.DomUtil.create("div","leaflet-popup");this._closeButton=L.DomUtil.create("a","leaflet-popup-close-button",this._container);this._closeButton.href="#close";this._closeButton.onclick=L.Util.bind(this._onCloseButtonClick,this);this._wrapper=L.DomUtil.create("div","leaflet-popup-content-wrapper",this._container);L.DomEvent.disableClickPropagation(this._wrapper);this._contentNode=L.DomUtil.create("div","leaflet-popup-content",this._wrapper);this._tipContainer=L.DomUtil.create("div","leaflet-popup-tip-container",
-this._container);this._tip=L.DomUtil.create("div","leaflet-popup-tip",this._tipContainer)},_update:function(){this._container.style.visibility="hidden";this._updateContent();this._updateLayout();this._updatePosition();this._container.style.visibility="";this._adjustPan()},_updateContent:function(){if(this._content)typeof this._content=="string"?this._contentNode.innerHTML=this._content:(this._contentNode.innerHTML="",this._contentNode.appendChild(this._content))},_updateLayout:function(){this._container.style.width=
-"";this._container.style.whiteSpace="nowrap";var a=this._container.offsetWidth;this._container.style.width=(a>this.options.maxWidth?this.options.maxWidth:a)+"px";this._container.style.whiteSpace="";this._containerWidth=this._container.offsetWidth},_updatePosition:function(){var a=this._map.latLngToLayerPoint(this._latlng);this._containerBottom=-a.y-this.options.offset.y;this._containerLeft=a.x-Math.round(this._containerWidth/2)+this.options.offset.x;this._container.style.bottom=this._containerBottom+
-"px";this._container.style.left=this._containerLeft+"px"},_adjustPan:function(){if(this.options.autoPan){var a=this._container.offsetHeight,b=this._map.layerPointToContainerPoint(new L.Point(this._containerLeft,-a-this._containerBottom)),c=new L.Point(0,0),d=this.options.autoPanPadding,e=this._map.getSize();if(b.x<0)c.x=b.x-d.x;if(b.x+this._containerWidth>e.x)c.x=b.x+this._containerWidth-e.x+d.x;if(b.y<0)c.y=b.y-d.y;if(b.y+a>e.y)c.y=b.y+a-e.y+d.y;(c.x||c.y)&&this._map.panBy(c)}},_onCloseButtonClick:function(a){this._close();
-L.DomEvent.stop(a)}});L.Icon=L.Class.extend({iconUrl:L.ROOT_URL+"images/marker.png",shadowUrl:L.ROOT_URL+"images/marker-shadow.png",iconSize:new L.Point(25,41),shadowSize:new L.Point(41,41),iconAnchor:new L.Point(13,41),popupAnchor:new L.Point(0,-33),initialize:function(a){if(a)this.iconUrl=a},createIcon:function(){return this._createIcon("icon")},createShadow:function(){return this._createIcon("shadow")},_createIcon:function(a){var b=this[a+"Size"],c=this[a+"Url"],d=this._createImg(c);if(!c)return null;d.className="leaflet-marker-"+
-a;d.style.marginLeft=-this.iconAnchor.x+"px";d.style.marginTop=-this.iconAnchor.y+"px";if(b)d.style.width=b.x+"px",d.style.height=b.y+"px";return d},_createImg:function(a){var b;L.Browser.ie6?(b=document.createElement("div"),b.style.filter='progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+a+'")'):(b=document.createElement("img"),b.src=a);return b}});L.Marker=L.Class.extend({includes:L.Mixin.Events,options:{icon:new L.Icon,title:"",clickable:!0,draggable:!1},initialize:function(a,b){L.Util.setOptions(this,b);this._latlng=a},onAdd:function(a){this._map=a;this._initIcon();a.on("viewreset",this._reset,this);this._reset()},onRemove:function(a){this._removeIcon();a.off("viewreset",this._reset,this)},getLatLng:function(){return this._latlng},setLatLng:function(a){this._latlng=a;this._reset()},setIcon:function(a){this._removeIcon();this._icon=this._shadow=
-null;this.options.icon=a;this._initIcon()},_initIcon:function(){if(!this._icon){this._icon=this.options.icon.createIcon();if(this.options.title)this._icon.title=this.options.title;this._initInteraction()}if(!this._shadow)this._shadow=this.options.icon.createShadow();this._map._panes.markerPane.appendChild(this._icon);this._shadow&&this._map._panes.shadowPane.appendChild(this._shadow)},_removeIcon:function(){this._map._panes.markerPane.removeChild(this._icon);this._shadow&&this._map._panes.shadowPane.removeChild(this._shadow)},
-_reset:function(){var a=this._map.latLngToLayerPoint(this._latlng).round();L.DomUtil.setPosition(this._icon,a);this._shadow&&L.DomUtil.setPosition(this._shadow,a);this._icon.style.zIndex=a.y},_initInteraction:function(){if(this.options.clickable){this._icon.className+=" leaflet-clickable";L.DomEvent.addListener(this._icon,"click",this._onMouseClick,this);for(var a=["dblclick","mousedown","mouseover","mouseout"],b=0;b<a.length;b++)L.DomEvent.addListener(this._icon,a[b],this._fireMouseEvent,this)}if(L.Handler.MarkerDrag)this.dragging=
-new L.Handler.MarkerDrag(this),this.options.draggable&&this.dragging.enable()},_onMouseClick:function(a){L.DomEvent.stopPropagation(a);(!this.dragging||!this.dragging.moved())&&this.fire(a.type)},_fireMouseEvent:function(a){this.fire(a.type);L.DomEvent.stopPropagation(a)}});L.Marker.include({openPopup:function(){this._popup.setLatLng(this._latlng);this._map.openPopup(this._popup);return this},closePopup:function(){this._popup&&this._popup._close()},bindPopup:function(a,b){b=L.Util.extend({offset:this.options.icon.popupAnchor},b);this._popup=new L.Popup(b);this._popup.setContent(a);this.on("click",this.openPopup,this);return this}});L.Path=L.Class.extend({includes:[L.Mixin.Events],statics:function(){return{SVG_NS:"http://www.w3.org/2000/svg",SVG:!(!document.createElementNS||!document.createElementNS("http://www.w3.org/2000/svg","svg").createSVGRect),CLIP_PADDING:0.5}}(),options:{stroke:!0,color:"#0033ff",weight:5,opacity:0.5,fill:!1,fillColor:null,fillOpacity:0.2,clickable:!0,updateOnMoveEnd:!1},initialize:function(a){L.Util.setOptions(this,a)},onAdd:function(a){this._map=a;this._initElements();this._initEvents();this.projectLatlngs();
-this._updatePath();a.on("viewreset",this.projectLatlngs,this);this._updateTrigger=this.options.updateOnMoveEnd?"moveend":"viewreset";a.on(this._updateTrigger,this._updatePath,this)},onRemove:function(a){a._pathRoot.removeChild(this._container);a.off("viewreset",this._projectLatlngs,this);a.off(this._updateTrigger,this._updatePath,this)},projectLatlngs:function(){},getPathString:function(){},setStyle:function(a){L.Util.setOptions(this,a);this._path&&this._updateStyle()},_initElements:function(){this._initRoot();
-this._initPath();this._initStyle()},_initRoot:function(){if(!this._map._pathRoot)this._map._pathRoot=this._createElement("svg"),this._map._panes.overlayPane.appendChild(this._map._pathRoot),this._map.on("moveend",this._updateSvgViewport,this),this._updateSvgViewport()},_updateSvgViewport:function(){this._updateViewport();var a=this._map._pathViewport,b=a.min,c=a.max,a=c.x-b.x,c=c.y-b.y,d=this._map._pathRoot,e=this._map._panes.overlayPane;L.Browser.mobileWebkit&&e.removeChild(d);L.DomUtil.setPosition(d,
-b);d.setAttribute("width",a);d.setAttribute("height",c);d.setAttribute("viewBox",[b.x,b.y,a,c].join(" "));L.Browser.mobileWebkit&&e.appendChild(d)},_updateViewport:function(){var a=L.Path.CLIP_PADDING,b=this._map.getSize(),c=L.DomUtil.getPosition(this._map._mapPane).multiplyBy(-1).subtract(b.multiplyBy(a)),a=c.add(b.multiplyBy(1+a*2));this._map._pathViewport=new L.Bounds(c,a)},_initPath:function(){this._container=this._createElement("g");this._path=this._createElement("path");this._container.appendChild(this._path);
-this._map._pathRoot.appendChild(this._container)},_initStyle:function(){this.options.stroke&&(this._path.setAttribute("stroke-linejoin","round"),this._path.setAttribute("stroke-linecap","round"));this.options.fill?this._path.setAttribute("fill-rule","evenodd"):this._path.setAttribute("fill","none");this._updateStyle()},_updateStyle:function(){this.options.stroke&&(this._path.setAttribute("stroke",this.options.color),this._path.setAttribute("stroke-opacity",this.options.opacity),this._path.setAttribute("stroke-width",
-this.options.weight));this.options.fill&&(this._path.setAttribute("fill",this.options.fillColor||this.options.color),this._path.setAttribute("fill-opacity",this.options.fillOpacity))},_updatePath:function(){var a=this.getPathString();a||(a="M0 0");this._path.setAttribute("d",a)},_createElement:function(a){return document.createElementNS(L.Path.SVG_NS,a)},_initEvents:function(){if(this.options.clickable){L.Path.VML||this._path.setAttribute("class","leaflet-clickable");L.DomEvent.addListener(this._container,
-"click",this._onMouseClick,this);for(var a=["dblclick","mousedown","mouseover","mouseout"],b=0;b<a.length;b++)L.DomEvent.addListener(this._container,a[b],this._fireMouseEvent,this)}},_onMouseClick:function(a){(!this._map.dragging||!this._map.dragging.moved())&&this._fireMouseEvent(a)},_fireMouseEvent:function(a){this.hasEventListeners(a.type)&&(this.fire(a.type,{latlng:this._map.mouseEventToLatLng(a),layerPoint:this._map.mouseEventToLayerPoint(a)}),L.DomEvent.stopPropagation(a))},_redraw:function(){this.projectLatlngs();
-this._updatePath()}});L.Path.VML=function(){var a=document.createElement("div");a.innerHTML='<v:shape adj="1"/>';a=a.firstChild;a.style.behavior="url(#default#VML)";return a&&typeof a.adj=="object"}();
-L.Path=L.Path.SVG||!L.Path.VML?L.Path:L.Path.extend({statics:{CLIP_PADDING:0.02},_createElement:function(){try{return document.namespaces.add("lvml","urn:schemas-microsoft-com:vml"),function(a){return document.createElement("<lvml:"+a+' class="lvml">')}}catch(a){return function(a){return document.createElement("<"+a+' xmlns="urn:schemas-microsoft.com:vml" class="lvml">')}}}(),_initRoot:function(){if(!this._map._pathRoot)this._map._pathRoot=document.createElement("div"),this._map._pathRoot.className=
-"leaflet-vml-container",this._map._panes.overlayPane.appendChild(this._map._pathRoot),this._map.on("moveend",this._updateViewport,this),this._updateViewport()},_initPath:function(){this._container=this._createElement("shape");this._container.className+=" leaflet-vml-shape"+(this.options.clickable?" leaflet-clickable":"");this._container.coordsize="1 1";this._path=this._createElement("path");this._container.appendChild(this._path);this._map._pathRoot.appendChild(this._container)},_initStyle:function(){this.options.stroke?
-(this._stroke=this._createElement("stroke"),this._stroke.endcap="round",this._container.appendChild(this._stroke)):this._container.stroked=!1;this.options.fill?(this._container.filled=!0,this._fill=this._createElement("fill"),this._container.appendChild(this._fill)):this._container.filled=!1;this._updateStyle()},_updateStyle:function(){if(this.options.stroke)this._stroke.weight=this.options.weight+"px",this._stroke.color=this.options.color,this._stroke.opacity=this.options.opacity;if(this.options.fill)this._fill.color=
-this.options.fillColor||this.options.color,this._fill.opacity=this.options.fillOpacity},_updatePath:function(){this._container.style.display="none";this._path.v=this.getPathString()+" ";this._container.style.display=""}});L.Path.include({bindPopup:function(a,b){if(!this._popup||this._popup.options!==b)this._popup=new L.Popup(b);this._popup.setContent(a);if(!this._openPopupAdded)this.on("click",this._openPopup,this),this._openPopupAdded=!0;return this},_openPopup:function(a){this._popup.setLatLng(a.latlng);this._map.openPopup(this._popup)}});L.Polyline=L.Path.extend({initialize:function(a,b){L.Path.prototype.initialize.call(this,b);this._latlngs=a},options:{smoothFactor:1,noClip:!1,updateOnMoveEnd:!0},projectLatlngs:function(){this._originalPoints=[];for(var a=0,b=this._latlngs.length;a<b;a++)this._originalPoints[a]=this._map.latLngToLayerPoint(this._latlngs[a])},getPathString:function(){for(var a=0,b=this._parts.length,c="";a<b;a++)c+=this._getPathPartStr(this._parts[a]);return c},getLatLngs:function(){return this._latlngs},setLatLngs:function(a){this._latlngs=
-a;this._redraw();return this},addLatLng:function(a){this._latlngs.push(a);this._redraw();return this},spliceLatLngs:function(){var a=[].splice.apply(this._latlngs,arguments);this._redraw();return a},_getPathPartStr:function(a){for(var b=L.Path.VML,c=0,d=a.length,e="",f;c<d;c++)f=a[c],b&&f._round(),e+=(c?"L":"M")+f.x+" "+f.y;return e},_clipPoints:function(){var a=this._originalPoints,b=a.length,c,d,e;if(this.options.noClip)this._parts=[a];else{var f=this._parts=[],g=this._map._pathViewport,h=L.LineUtil;
-for(d=c=0;c<b-1;c++)if(e=h.clipSegment(a[c],a[c+1],g,c))if(f[d]=f[d]||[],f[d].push(e[0]),e[1]!=a[c+1]||c==b-2)f[d].push(e[1]),d++}},_simplifyPoints:function(){for(var a=this._parts,b=L.LineUtil,c=0,d=a.length;c<d;c++)a[c]=b.simplify(a[c],this.options.smoothFactor)},_updatePath:function(){this._clipPoints();this._simplifyPoints();L.Path.prototype._updatePath.call(this)}});L.Polygon=L.Polyline.extend({options:{fill:!0},initialize:function(a,b){L.Polyline.prototype.initialize.call(this,a,b);if(a[0]instanceof Array)this._latlngs=a[0],this._holes=a.slice(1)},projectLatlngs:function(){L.Polyline.prototype.projectLatlngs.call(this);this._holePoints=[];if(this._holes)for(var a=0,b=this._holes.length;a<b;a++){this._holePoints[a]=[];for(var c=0,d=this._holes[a].length;c<d;c++)this._holePoints[a][c]=this._map.latLngToLayerPoint(this._holes[a][c])}},_clipPoints:function(){var a=
-[];this._parts=[this._originalPoints].concat(this._holePoints);if(!this.options.noClip){for(var b=0,c=this._parts.length;b<c;b++){var d=L.PolyUtil.clipPolygon(this._parts[b],this._map._pathViewport);d.length&&a.push(d)}this._parts=a}},_getPathPartStr:function(a){return L.Polyline.prototype._getPathPartStr.call(this,a)+(L.Path.SVG?"z":"x")}});(function(){function a(a){return L.FeatureGroup.extend({initialize:function(c,d){this._layers={};for(var e=0,f=c.length;e<f;e++)this.addLayer(new a(c[e],d))},setStyle:function(a){for(var b in this._layers)this._layers.hasOwnProperty(b)&&this._layers[b].setStyle&&this._layers[b].setStyle(a)}})}L.MultiPolyline=a(L.Polyline);L.MultiPolygon=a(L.Polygon)})();L.Circle=L.Path.extend({initialize:function(a,b,c){L.Path.prototype.initialize.call(this,c);this._latlng=a;this._mRadius=b},options:{fill:!0},setLatLng:function(a){this._latlng=a;this._redraw();return this},setRadius:function(a){this._mRadius=a;this._redraw();return this},projectLatlngs:function(){var a=this._map.options.scale(this._map._zoom);this._point=this._map.latLngToLayerPoint(this._latlng);this._radius=this._mRadius/40075017*a},getPathString:function(){var a=this._point,b=this._radius;return L.Path.SVG?
-"M"+a.x+","+(a.y-b)+"A"+b+","+b+",0,1,1,"+(a.x-0.1)+","+(a.y-b)+" z":(a._round(),b=Math.round(b),"AL "+a.x+","+a.y+" "+b+","+b+" 0,23592600")}});L.CircleMarker=L.Circle.extend({options:{radius:10,weight:2},initialize:function(a,b){L.Circle.prototype.initialize.call(this,a,null,b);this._radius=this.options.radius},projectLatlngs:function(){this._point=this._map.latLngToLayerPoint(this._latlng)},setRadius:function(a){this._radius=a;this._redraw();return this}});L.GeoJSON=L.LayerGroup.extend({includes:L.Mixin.Events,initialize:function(a,b){L.Util.setOptions(this,b);this._geojson=a;this._layers={};a&&this.addGeoJSON(a)},addGeoJSON:function(a){if(a.features)for(var b=0,c=a.features.length;b<c;b++)this.addGeoJSON(a.features[b]);else b=a.type=="Feature"?a.geometry:a,c=L.GeoJSON.geometryToLayer(b,this.options.pointToLayer),this.fire("featureparse",{layer:c,properties:a.properties,geometryType:b.type,bbox:a.bbox,id:a.id}),this.addLayer(c)}});
-L.Util.extend(L.GeoJSON,{geometryToLayer:function(a,b){var c=a.coordinates,d,e,f,g=[];switch(a.type){case "Point":return d=this.coordsToLatLng(c),b?b(d):new L.Marker(d);case "MultiPoint":e=0;for(f=c.length;e<f;e++)d=this.coordsToLatLng(c[e]),d=b?b(d):new L.Marker(d),g.push(d);return new L.FeatureGroup(g);case "LineString":return c=this.coordsToLatLngs(c),new L.Polyline(c);case "Polygon":return c=this.coordsToLatLngs(c,1),new L.Polygon(c);case "MultiLineString":return c=this.coordsToLatLngs(c,1),new L.MultiPolyline(c);
-case "MultiPolygon":return c=this.coordsToLatLngs(c,2),new L.MultiPolygon(c);case "GeometryCollection":e=0;for(f=a.geometries.length;e<f;e++)d=this.geometryToLayer(a.geometries[e]),g.push(d);return new L.FeatureGroup(g);default:throw Error("Invalid GeoJSON object.");}},coordsToLatLng:function(a,b){var c=parseFloat(a[b?0:1]),d=parseFloat(a[b?1:0]);return new L.LatLng(c,d)},coordsToLatLngs:function(a,b,c){var d,e=[],f,g=a.length;for(f=0;f<g;f++)d=b?this.coordsToLatLngs(a[f],b-1,c):this.coordsToLatLng(a[f],
-c),e.push(d);return e}});L.Handler=L.Class.extend({initialize:function(a){this._map=a},enabled:function(){return!!this._enabled}});L.Handler.MapDrag=L.Handler.extend({enable:function(){if(!this._enabled){if(!this._draggable)this._draggable=new L.Draggable(this._map._mapPane,this._map._container),this._draggable.on("dragstart",this._onDragStart,this),this._draggable.on("drag",this._onDrag,this),this._draggable.on("dragend",this._onDragEnd,this);this._draggable.enable();this._enabled=!0}},disable:function(){if(this._enabled)this._draggable.disable(),this._enabled=!1},moved:function(){return this._draggable._moved},_onDragStart:function(){this._map.fire("movestart");
-this._map.fire("dragstart")},_onDrag:function(){this._map.fire("move");this._map.fire("drag")},_onDragEnd:function(){this._map.fire("moveend");this._map.fire("dragend")}});L.Handler.TouchZoom=L.Handler.extend({enable:function(){if(L.Browser.mobileWebkit&&!this._enabled)L.DomEvent.addListener(this._map._container,"touchstart",this._onTouchStart,this),this._enabled=!0},disable:function(){if(this._enabled)L.DomEvent.removeListener(this._map._container,"touchstart",this._onTouchStart,this),this._enabled=!1},_onTouchStart:function(a){if(a.touches&&!(a.touches.length!=2||this._map._animatingZoom)){var b=this._map.mouseEventToLayerPoint(a.touches[0]),c=this._map.mouseEventToLayerPoint(a.touches[1]),
-d=this._map.containerPointToLayerPoint(this._map.getSize().divideBy(2));this._startCenter=b.add(c).divideBy(2,!0);this._startDist=b.distanceTo(c);this._moved=!1;this._zooming=!0;this._centerOffset=d.subtract(this._startCenter);L.DomEvent.addListener(document,"touchmove",this._onTouchMove,this);L.DomEvent.addListener(document,"touchend",this._onTouchEnd,this);L.DomEvent.preventDefault(a)}},_onTouchMove:function(a){if(a.touches&&a.touches.length==2){if(!this._moved)this._map._mapPane.className+=" leaflet-zoom-anim",
-this._map._prepareTileBg(),this._moved=!0;var b=this._map.mouseEventToLayerPoint(a.touches[0]),c=this._map.mouseEventToLayerPoint(a.touches[1]);this._scale=b.distanceTo(c)/this._startDist;this._delta=b.add(c).divideBy(2,!0).subtract(this._startCenter);this._map._tileBg.style.webkitTransform=[L.DomUtil.getTranslateString(this._delta),L.DomUtil.getScaleString(this._scale,this._startCenter)].join(" ");L.DomEvent.preventDefault(a)}},_onTouchEnd:function(){if(this._moved&&this._zooming){this._zooming=
-!1;var a=this._map.getZoom(),b=Math.log(this._scale)/Math.LN2,b=this._map._limitZoom(a+(b>0?Math.ceil(b):Math.floor(b))),a=b-a,c=this._centerOffset.subtract(this._delta).divideBy(this._scale),d=this._map.unproject(this._map.getPixelOrigin().add(this._startCenter).add(c));L.DomEvent.removeListener(document,"touchmove",this._onTouchMove);L.DomEvent.removeListener(document,"touchend",this._onTouchEnd);this._map._runAnimation(d,b,Math.pow(2,a)/this._scale,this._startCenter.add(c))}}});L.Handler.ScrollWheelZoom=L.Handler.extend({enable:function(){if(!this._enabled)L.DomEvent.addListener(this._map._container,"mousewheel",this._onWheelScroll,this),this._delta=0,this._enabled=!0},disable:function(){if(this._enabled)L.DomEvent.removeListener(this._map._container,"mousewheel",this._onWheelScroll),this._enabled=!1},_onWheelScroll:function(a){this._delta+=L.DomEvent.getWheelDelta(a);this._lastMousePos=this._map.mouseEventToContainerPoint(a);clearTimeout(this._timer);this._timer=setTimeout(L.Util.bind(this._performZoom,
-this),50);L.DomEvent.preventDefault(a)},_performZoom:function(){var a=Math.round(this._delta);this._delta=0;if(a){var b=this._getCenterForScrollWheelZoom(this._lastMousePos,a),a=this._map.getZoom()+a;this._map._limitZoom(a)!=this._map._zoom&&this._map.setView(b,a)}},_getCenterForScrollWheelZoom:function(a,b){var c=this._map.getPixelBounds().getCenter(),d=this._map.getSize().divideBy(2),d=a.subtract(d).multiplyBy(1-Math.pow(2,-b));return this._map.unproject(c.add(d),this._map._zoom,!0)}});L.Handler.DoubleClickZoom=L.Handler.extend({enable:function(){if(!this._enabled)this._map.on("dblclick",this._onDoubleClick,this._map),this._enabled=!0},disable:function(){if(this._enabled)this._map.off("dblclick",this._onDoubleClick,this._map),this._enabled=!1},_onDoubleClick:function(a){this.setView(a.latlng,this._zoom+1)}});L.Handler.ShiftDragZoom=L.Handler.extend({initialize:function(a){this._map=a;this._container=a._container;this._pane=a._panes.overlayPane},enable:function(){if(!this._enabled)L.DomEvent.addListener(this._container,"mousedown",this._onMouseDown,this),this._enabled=!0},disable:function(){if(this._enabled)L.DomEvent.removeListener(this._container,"mousedown",this._onMouseDown),this._enabled=!1},_onMouseDown:function(a){if(!a.shiftKey||a.which!=1&&a.button!=1)return!1;L.DomUtil.disableTextSelection();
-this._startLayerPoint=this._map.mouseEventToLayerPoint(a);this._box=L.DomUtil.create("div","leaflet-zoom-box",this._pane);L.DomUtil.setPosition(this._box,this._startLayerPoint);this._container.style.cursor="crosshair";L.DomEvent.addListener(document,"mousemove",this._onMouseMove,this);L.DomEvent.addListener(document,"mouseup",this._onMouseUp,this);L.DomEvent.preventDefault(a)},_onMouseMove:function(a){var b=this._map.mouseEventToLayerPoint(a),a=b.x-this._startLayerPoint.x,c=b.y-this._startLayerPoint.y,
-b=new L.Point(Math.min(b.x,this._startLayerPoint.x),Math.min(b.y,this._startLayerPoint.y));L.DomUtil.setPosition(this._box,b);this._box.style.width=Math.abs(a)-4+"px";this._box.style.height=Math.abs(c)-4+"px"},_onMouseUp:function(a){this._pane.removeChild(this._box);this._container.style.cursor="";L.DomUtil.enableTextSelection();L.DomEvent.removeListener(document,"mousemove",this._onMouseMove);L.DomEvent.removeListener(document,"mouseup",this._onMouseUp);a=this._map.mouseEventToLayerPoint(a);this._map.fitBounds(new L.LatLngBounds(this._map.layerPointToLatLng(this._startLayerPoint),
-this._map.layerPointToLatLng(a)))}});L.Handler.MarkerDrag=L.Handler.extend({initialize:function(a){this._marker=a},enable:function(){if(!this._enabled){if(!this._draggable)this._draggable=new L.Draggable(this._marker._icon,this._marker._icon),this._draggable.on("dragstart",this._onDragStart,this),this._draggable.on("drag",this._onDrag,this),this._draggable.on("dragend",this._onDragEnd,this);this._draggable.enable();this._enabled=!0}},disable:function(){if(this._enabled)this._draggable.disable(),this._enabled=!1},moved:function(){return this._draggable&&
-this._draggable._moved},_onDragStart:function(){this._marker.closePopup();this._marker.fire("movestart");this._marker.fire("dragstart")},_onDrag:function(){var a=L.DomUtil.getPosition(this._marker._icon);L.DomUtil.setPosition(this._marker._shadow,a);this._marker._latlng=this._marker._map.layerPointToLatLng(a);this._marker.fire("move");this._marker.fire("drag")},_onDragEnd:function(){this._marker.fire("moveend");this._marker.fire("dragend")}});L.Control={};L.Control.Position={TOP_LEFT:"topLeft",TOP_RIGHT:"topRight",BOTTOM_LEFT:"bottomLeft",BOTTOM_RIGHT:"bottomRight"};L.Control.Zoom=L.Class.extend({onAdd:function(a){this._map=a;this._container=L.DomUtil.create("div","leaflet-control-zoom");this._zoomInButton=this._createButton("Zoom in","leaflet-control-zoom-in",this._map.zoomIn,this._map);this._zoomOutButton=this._createButton("Zoom out","leaflet-control-zoom-out",this._map.zoomOut,this._map);this._container.appendChild(this._zoomInButton);this._container.appendChild(this._zoomOutButton)},getContainer:function(){return this._container},getPosition:function(){return L.Control.Position.TOP_LEFT},
-_createButton:function(a,b,c,d){var e=document.createElement("a");e.href="#";e.title=a;e.className=b;L.DomEvent.disableClickPropagation(e);L.DomEvent.addListener(e,"click",L.DomEvent.preventDefault);L.DomEvent.addListener(e,"click",c,d);return e}});L.Control.Attribution=L.Class.extend({onAdd:function(a){this._container=L.DomUtil.create("div","leaflet-control-attribution");this._map=a;this._prefix='Powered by <a href="http://leaflet.cloudmade.com">Leaflet</a>';this._attributions={};this._update()},getPosition:function(){return L.Control.Position.BOTTOM_RIGHT},getContainer:function(){return this._container},setPrefix:function(a){this._prefix=a},addAttribution:function(a){a&&(this._attributions[a]=!0,this._update())},removeAttribution:function(a){a&&
-(delete this._attributions[a],this._update())},_update:function(){if(this._map){var a=[],b;for(b in this._attributions)this._attributions.hasOwnProperty(b)&&a.push(b);b=[];this._prefix&&b.push(this._prefix);a.length&&b.push(a.join(", "));this._container.innerHTML=b.join(" — ")}}});L.Map=L.Class.extend({includes:L.Mixin.Events,options:{crs:L.CRS.EPSG3857||L.CRS.EPSG4326,scale:function(a){return 256*(1<<a)},center:null,zoom:null,layers:[],dragging:!0,touchZoom:L.Browser.mobileWebkit&&!L.Browser.android,scrollWheelZoom:!L.Browser.mobileWebkit,doubleClickZoom:!0,shiftDragZoom:!0,zoomControl:!0,attributionControl:!0,fadeAnimation:L.DomUtil.TRANSITION&&!L.Browser.android,zoomAnimation:L.DomUtil.TRANSITION&&!L.Browser.android&&!L.Browser.mobileOpera,trackResize:!0,closePopupOnClick:!0},
-initialize:function(a,b){L.Util.setOptions(this,b);this._container=L.DomUtil.get(a);this._initLayout();L.DomEvent&&(this._initEvents(),L.Handler&&this._initInteraction(),L.Control&&this._initControls());var c=this.options.center,d=this.options.zoom;c!==null&&d!==null&&this.setView(c,d,!0);c=this.options.layers;c=c instanceof Array?c:[c];this._tileLayersNum=0;this._initLayers(c)},setView:function(a,b){this._resetView(a,this._limitZoom(b));return this},setZoom:function(a){return this.setView(this.getCenter(),
-a)},zoomIn:function(){return this.setZoom(this._zoom+1)},zoomOut:function(){return this.setZoom(this._zoom-1)},fitBounds:function(a){var b=this.getBoundsZoom(a);return this.setView(a.getCenter(),b)},fitWorld:function(){var a=new L.LatLng(-60,-170),b=new L.LatLng(85,179);return this.fitBounds(new L.LatLngBounds(a,b))},panTo:function(a){return this.setView(a,this._zoom)},panBy:function(a){this.fire("movestart");this._rawPanBy(a);this.fire("move");this.fire("moveend");return this},addLayer:function(a){var b=
-L.Util.stamp(a);if(this._layers[b])return this;this._layers[b]=a;if(a.options&&!isNaN(a.options.maxZoom))this._layersMaxZoom=Math.max(this._layersMaxZoom||0,a.options.maxZoom);if(a.options&&!isNaN(a.options.minZoom))this._layersMinZoom=Math.min(this._layersMinZoom||Infinity,a.options.minZoom);this.options.zoomAnimation&&L.TileLayer&&a instanceof L.TileLayer&&(this._tileLayersNum++,a.on("load",this._onTileLayerLoad,this));this.attributionControl&&a.getAttribution&&this.attributionControl.addAttribution(a.getAttribution());
-b=function(){a.onAdd(this);this.fire("layeradd",{layer:a})};if(this._loaded)b.call(this);else this.on("load",b,this);return this},removeLayer:function(a){var b=L.Util.stamp(a);this._layers[b]&&(a.onRemove(this),delete this._layers[b],this.options.zoomAnimation&&L.TileLayer&&a instanceof L.TileLayer&&(this._tileLayersNum--,a.off("load",this._onTileLayerLoad,this)),this.attributionControl&&a.getAttribution&&this.attributionControl.removeAttribution(a.getAttribution()),this.fire("layerremove",{layer:a}));
-return this},invalidateSize:function(){this._sizeChanged=!0;this.fire("move");clearTimeout(this._sizeTimer);this._sizeTimer=setTimeout(L.Util.bind(function(){this.fire("moveend")},this),200);return this},getCenter:function(a){var b=this.getSize().divideBy(2);return this.unproject(this._getTopLeftPoint().add(b),this._zoom,a)},getZoom:function(){return this._zoom},getBounds:function(){var a=this.getPixelBounds(),b=this.unproject(new L.Point(a.min.x,a.max.y)),a=this.unproject(new L.Point(a.max.x,a.min.y));
-return new L.LatLngBounds(b,a)},getMinZoom:function(){return isNaN(this.options.minZoom)?this._layersMinZoom||0:this.options.minZoom},getMaxZoom:function(){return isNaN(this.options.maxZoom)?this._layersMaxZoom||Infinity:this.options.maxZoom},getBoundsZoom:function(a){var b=this.getSize(),c=this.getMinZoom(),d=this.getMaxZoom(),e=a.getNorthEast(),a=a.getSouthWest(),f,g;do c++,f=this.project(e,c),g=this.project(a,c),f=new L.Point(f.x-g.x,g.y-f.y);while(f.x<=b.x&&f.y<=b.y&&c<=d);return c-1},getSize:function(){if(!this._size||
-this._sizeChanged)this._size=new L.Point(this._container.clientWidth,this._container.clientHeight),this._sizeChanged=!1;return this._size},getPixelBounds:function(){var a=this._getTopLeftPoint(),b=this.getSize();return new L.Bounds(a,a.add(b))},getPixelOrigin:function(){return this._initialTopLeftPoint},getPanes:function(){return this._panes},mouseEventToContainerPoint:function(a){return L.DomEvent.getMousePosition(a,this._container)},mouseEventToLayerPoint:function(a){return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(a))},
-mouseEventToLatLng:function(a){return this.layerPointToLatLng(this.mouseEventToLayerPoint(a))},containerPointToLayerPoint:function(a){return a.subtract(L.DomUtil.getPosition(this._mapPane))},layerPointToContainerPoint:function(a){return a.add(L.DomUtil.getPosition(this._mapPane))},layerPointToLatLng:function(a){return this.unproject(a.add(this._initialTopLeftPoint))},latLngToLayerPoint:function(a){return this.project(a)._subtract(this._initialTopLeftPoint)},project:function(a,b){b=typeof b=="undefined"?
-this._zoom:b;return this.options.crs.latLngToPoint(a,this.options.scale(b))},unproject:function(a,b,c){b=typeof b=="undefined"?this._zoom:b;return this.options.crs.pointToLatLng(a,this.options.scale(b),c)},_initLayout:function(){var a=this._container;a.className+=" leaflet-container";this.options.fadeAnimation&&(a.className+=" leaflet-fade-anim");var b=L.DomUtil.getStyle(a,"position");if(b!="absolute"&&b!="relative")a.style.position="relative";this._initPanes();this._initControlPos&&this._initControlPos()},
-_initPanes:function(){var a=this._panes={};this._mapPane=a.mapPane=this._createPane("leaflet-map-pane",this._container);this._tilePane=a.tilePane=this._createPane("leaflet-tile-pane",this._mapPane);this._objectsPane=a.objectsPane=this._createPane("leaflet-objects-pane",this._mapPane);a.shadowPane=this._createPane("leaflet-shadow-pane");a.overlayPane=this._createPane("leaflet-overlay-pane");a.markerPane=this._createPane("leaflet-marker-pane");a.popupPane=this._createPane("leaflet-popup-pane")},_createPane:function(a,
-b){return L.DomUtil.create("div",a,b||this._objectsPane)},_resetView:function(a,b,c){var d=this._zoom!=b;this.fire("movestart");this._zoom=b;this._initialTopLeftPoint=this._getNewTopLeftPoint(a);c?this._initialTopLeftPoint._add(L.DomUtil.getPosition(this._mapPane)):L.DomUtil.setPosition(this._mapPane,new L.Point(0,0));this._tileLayersToLoad=this._tileLayersNum;this.fire("viewreset");this.fire("move");d&&this.fire("zoomend");this.fire("moveend");if(!this._loaded)this._loaded=!0,this.fire("load")},
-_initLayers:function(a){this._layers={};for(var b=0,c=a.length;b<c;b++)this.addLayer(a[b])},_initControls:function(){this.options.zoomControl&&this.addControl(new L.Control.Zoom);if(this.options.attributionControl)this.attributionControl=new L.Control.Attribution,this.addControl(this.attributionControl)},_rawPanBy:function(a){var b=L.DomUtil.getPosition(this._mapPane);L.DomUtil.setPosition(this._mapPane,b.subtract(a))},_initEvents:function(){L.DomEvent.addListener(this._container,"click",this._onMouseClick,
-this);for(var a=["dblclick","mousedown","mouseenter","mouseleave","mousemove"],b=0;b<a.length;b++)L.DomEvent.addListener(this._container,a[b],this._fireMouseEvent,this);this.options.trackResize&&L.DomEvent.addListener(window,"resize",this.invalidateSize,this)},_onMouseClick:function(a){if(!this.dragging||!this.dragging.moved())this.fire("pre"+a.type),this._fireMouseEvent(a)},_fireMouseEvent:function(a){var b=a.type,b=b=="mouseenter"?"mouseover":b=="mouseleave"?"mouseout":b;this.hasEventListeners(b)&&
-this.fire(b,{latlng:this.mouseEventToLatLng(a),layerPoint:this.mouseEventToLayerPoint(a)})},_initInteraction:function(){var a={dragging:L.Handler.MapDrag,touchZoom:L.Handler.TouchZoom,doubleClickZoom:L.Handler.DoubleClickZoom,scrollWheelZoom:L.Handler.ScrollWheelZoom,shiftDragZoom:L.Handler.ShiftDragZoom},b;for(b in a)a.hasOwnProperty(b)&&a[b]&&(this[b]=new a[b](this),this.options[b]&&this[b].enable())},_onTileLayerLoad:function(){this._tileLayersToLoad--;if(this._tileLayersNum&&!this._tileLayersToLoad&&
-this._tileBg)clearTimeout(this._clearTileBgTimer),this._clearTileBgTimer=setTimeout(L.Util.bind(this._clearTileBg,this),500)},_getTopLeftPoint:function(){if(!this._loaded)throw Error("Set map center and zoom first.");return this._initialTopLeftPoint.subtract(L.DomUtil.getPosition(this._mapPane))},_getNewTopLeftPoint:function(a){var b=this.getSize().divideBy(2);return this.project(a).subtract(b).round()},_limitZoom:function(a){var b=this.getMinZoom(),c=this.getMaxZoom();return Math.max(b,Math.min(c,
-a))}});L.Map.include({locate:function(a){var b={timeout:1E4};L.Util.extend(b,a);navigator.geolocation?navigator.geolocation.getCurrentPosition(L.Util.bind(this._handleGeolocationResponse,this),L.Util.bind(this._handleGeolocationError,this),b):this.fire("locationerror",{code:0,message:"Geolocation not supported."});return this},locateAndSetView:function(a,b){this._setViewOnLocate=!0;this._maxLocateZoom=a||Infinity;return this.locate(b)},_handleGeolocationError:function(a){var a=a.code,b=a==1?"permission denied":
-a==2?"position unavailable":"timeout";if(this._setViewOnLocate)this.fitWorld(),this._setViewOnLocate=!1;this.fire("locationerror",{code:a,message:"Geolocation error: "+b+"."})},_handleGeolocationResponse:function(a){var b=180*a.coords.accuracy/4E7,c=b*2,d=a.coords.latitude,e=a.coords.longitude,f=new L.LatLng(d-b,e-c),b=new L.LatLng(d+b,e+c),f=new L.LatLngBounds(f,b);if(this._setViewOnLocate)b=Math.min(this.getBoundsZoom(f),this._maxLocateZoom),this.setView(f.getCenter(),b),this._setViewOnLocate=!1;
-this.fire("locationfound",{latlng:new L.LatLng(d,e),bounds:f,accuracy:a.coords.accuracy})}});L.Map.include({openPopup:function(a){this.closePopup();this._popup=a;return this.addLayer(a)},closePopup:function(){this._popup&&this.removeLayer(this._popup);return this}});L.Map.include(!L.Transition||!L.Transition.implemented()?{}:{setView:function(a,b,c){var b=this._limitZoom(b),d=this._zoom!=b;if(this._loaded&&!c&&this._layers&&(c=this._getNewTopLeftPoint(a).subtract(this._getTopLeftPoint()),d?this._zoomToIfCenterInView&&this._zoomToIfCenterInView(a,b,c):this._panByIfClose(c)))return this;this._resetView(a,b);return this},panBy:function(a){if(!this._panTransition)this._panTransition=new L.Transition(this._mapPane,{duration:0.3}),this._panTransition.on("step",this._onPanTransitionStep,
-this),this._panTransition.on("end",this._onPanTransitionEnd,this);this.fire(this,"movestart");this._panTransition.run({position:L.DomUtil.getPosition(this._mapPane).subtract(a)});return this},_onPanTransitionStep:function(){this.fire("move")},_onPanTransitionEnd:function(){this.fire("moveend")},_panByIfClose:function(a){if(this._offsetIsWithinView(a))return this.panBy(a),!0;return!1},_offsetIsWithinView:function(a,b){var c=b||1,d=this.getSize();return Math.abs(a.x)<=d.x*c&&Math.abs(a.y)<=d.y*c}});L.Map.include(!L.DomUtil.TRANSITION?{}:{_zoomToIfCenterInView:function(a,b,c){if(this._animatingZoom)return!0;if(!this.options.zoomAnimation)return!1;var d=Math.pow(2,b-this._zoom),c=c.divideBy(1-1/d);if(!this._offsetIsWithinView(c,1))return!1;this._mapPane.className+=" leaflet-zoom-anim";c=this.containerPointToLayerPoint(this.getSize().divideBy(2)).add(c);this._prepareTileBg();this._runAnimation(a,b,d,c);return!0},_runAnimation:function(a,b,c,d){this._animatingZoom=!0;this._animateToCenter=a;this._animateToZoom=
-b;a=L.DomUtil.TRANSFORM;if(L.Browser.gecko||window.opera)this._tileBg.style[a]+=" translate(0,0)";L.Browser.android?(this._tileBg.style[a+"Origin"]=d.x+"px "+d.y+"px",c="scale("+c+")"):c=L.DomUtil.getScaleString(c,d);L.Util.falseFn(this._tileBg.offsetWidth);d={};d[a]=this._tileBg.style[a]+" "+c;this._tileBg.transition.run(d)},_prepareTileBg:function(){if(!this._tileBg)this._tileBg=this._createPane("leaflet-tile-pane",this._mapPane),this._tileBg.style.zIndex=1;var a=this._tilePane,b=this._tileBg;b.style[L.DomUtil.TRANSFORM]=
-"";b.style.visibility="hidden";b.empty=!0;a.empty=!1;this._tilePane=this._panes.tilePane=b;this._tileBg=a;if(!this._tileBg.transition)this._tileBg.transition=new L.Transition(this._tileBg,{duration:0.3,easing:"cubic-bezier(0.25,0.1,0.25,0.75)"}),this._tileBg.transition.on("end",this._onZoomTransitionEnd,this);this._stopLoadingBgTiles()},_stopLoadingBgTiles:function(){for(var a=[].slice.call(this._tileBg.getElementsByTagName("img")),b=0,c=a.length;b<c;b++)if(!a[b].complete)a[b].src="",a[b].parentNode.removeChild(a[b])},
-_onZoomTransitionEnd:function(){this._restoreTileFront();L.Util.falseFn(this._tileBg.offsetWidth);this._resetView(this._animateToCenter,this._animateToZoom,!0);this._mapPane.className=this._mapPane.className.replace(" leaflet-zoom-anim","");this._animatingZoom=!1},_restoreTileFront:function(){this._tilePane.innerHTML="";this._tilePane.style.visibility="";this._tilePane.style.zIndex=2;this._tileBg.style.zIndex=1},_clearTileBg:function(){if(!this._animatingZoom&&!this.touchZoom._zooming)this._tileBg.innerHTML=
-""}});L.Map.include({addControl:function(a){a.onAdd(this);var b=a.getPosition(),c=this._controlCorners[b],a=a.getContainer();L.DomUtil.addClass(a,"leaflet-control");b.indexOf("bottom")!=-1?c.insertBefore(a,c.firstChild):c.appendChild(a);return this},removeControl:function(a){var b=this._controlCorners[a.getPosition()],c=a.getContainer();b.removeChild(c);if(a.onRemove)a.onRemove(this);return this},_initControlPos:function(){var a=this._controlCorners={},b=L.DomUtil.create("div","leaflet-control-container",
-this._container);L.Browser.mobileWebkit&&(b.className+=" leaflet-big-buttons");a.topLeft=L.DomUtil.create("div","leaflet-top leaflet-left",b);a.topRight=L.DomUtil.create("div","leaflet-top leaflet-right",b);a.bottomLeft=L.DomUtil.create("div","leaflet-bottom leaflet-left",b);a.bottomRight=L.DomUtil.create("div","leaflet-bottom leaflet-right",b)}});


diff -r 71ceede82775407793c71670ae2a5f063ff68aa4 -r fdc44a69a4814a753dd1b7e9a738a8f1c99bba33 yt/gui/reason/pyro_queue.py
--- /dev/null
+++ b/yt/gui/reason/pyro_queue.py
@@ -0,0 +1,67 @@
+"""
+Task queue for reason.
+
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: Michigan State University
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2012 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+"""
+
+import numpy as na
+
+from yt.funcs import *
+
+from yt.gui.reason.basic_repl import ProgrammaticREPL
+from yt.gui.reason.extdirect_repl import ExecutionThread
+from yt.gui.reason.bottle_mods import PayloadHandler
+from .utils import get_list_of_datasets
+
+class PyroQueueRoot(object):
+    def __init__(self, comm):
+        self.comm = comm
+        self.repl = ProgrammaticREPL()
+        self.execution_thread = ExecutionThread(self.repl)
+        self.payload_handler = PayloadHandler()
+        self.execution_thread.start()
+
+    def execute(self, code, hide = False):
+        mylog.info('Root sending out code.')
+        code = self.comm.comm.bcast(code, root=0)
+        task = {'type': 'code',
+                'code': code,
+                'hide': hide}
+        self.execution_thread.queue.put(task)
+
+    def deliver(self):
+        return self.payload_handler.deliver_payloads()
+
+class PyroQueueNonRoot(object):
+    def __init__(self, comm):
+        self.comm = comm
+        self.repl = ProgrammaticREPL()
+
+    def run(self):
+        while 1:
+            code = None
+            code = self.comm.comm.bcast(code, root=0)
+            mylog.info('Received commands from subcomm root.')
+            value = self.repl.execute(code)
+            


diff -r 71ceede82775407793c71670ae2a5f063ff68aa4 -r fdc44a69a4814a753dd1b7e9a738a8f1c99bba33 yt/gui/reason/utils.py
--- /dev/null
+++ b/yt/gui/reason/utils.py
@@ -0,0 +1,83 @@
+"""
+Utilities for Reason
+
+Author: Britton Smith <brittonsmith at gmail.com>
+Affiliation: Michigan State University
+Author: Matthew Turk <matthewturk at gmail.com>
+Affiliation: Columbia University
+Homepage: http://yt-project.org/
+License:
+  Copyright (C) 2011 Matthew Turk.  All Rights Reserved.
+
+  This file is part of yt.
+
+  yt is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+"""
+
+from .bottle_mods import PayloadHandler
+import base64
+import types
+
+def load_script(filename):
+    contents = open(filename).read()
+    payload_handler = PayloadHandler()
+    payload_handler.add_payload(
+        {'type': 'script',
+         'value': contents}
+    )
+    return
+
+def deliver_image(im):
+    if hasattr(im, 'read'):
+        img_data = base64.b64encode(im.read())
+    elif isinstance(im, types.StringTypes) and \
+         im.endswith(".png"):
+        img_data = base64.b64encode(open(im).read())
+    elif isinstance(im, types.StringTypes):
+        img_data = im
+    else:
+        raise RuntimeError
+    ph = PayloadHandler()
+    payload = {'type':'cell',
+               'output': '',
+               'input': '',
+               'raw_input': '',
+               'image_data':img_data}
+    ph.add_payload(payload)
+
+def get_list_of_datasets():
+    # Note that this instantiates the hierarchy.  This can be a costly
+    # event.  However, we're going to assume that it's okay, if you have
+    # decided to load up the parameter file.
+    from yt.data_objects.static_output import _cached_pfs
+    rv = []
+    for fn, pf in sorted(_cached_pfs.items()):
+        objs = []
+        pf_varname = "_cached_pfs['%s']" % (fn)
+        field_list = []
+        if pf._instantiated_hierarchy is not None: 
+            field_list = list(set(pf.h.field_list + pf.h.derived_field_list))
+            field_list = [dict(text = f) for f in sorted(field_list)]
+            for i,obj in enumerate(pf.h.objects):
+                try:
+                    name = str(obj)
+                except ReferenceError:
+                    continue
+                objs.append(dict(name=name, type=obj._type_name,
+                                 filename = '', field_list = [],
+                                 varname = "%s.h.objects[%s]" % (pf_varname, i)))
+        rv.append( dict(name = str(pf), children = objs, filename=fn,
+                        type = "parameter_file",
+                        varname = pf_varname, field_list = field_list) )
+    return rv


diff -r 71ceede82775407793c71670ae2a5f063ff68aa4 -r fdc44a69a4814a753dd1b7e9a738a8f1c99bba33 yt/gui/reason/widget_store.py
--- a/yt/gui/reason/widget_store.py
+++ b/yt/gui/reason/widget_store.py
@@ -40,8 +40,8 @@
 """
 
 class WidgetStore(dict):
-    def __init__(self, repl):
-        self.repl = weakref.proxy(repl)
+    def __init__(self, global_token = ""):
+        self._global_token = global_token
         self.payload_handler = PayloadHandler()
         super(WidgetStore, self).__init__()
 
@@ -143,7 +143,7 @@
     def create_mapview(self, widget_name):
         widget = self[widget_name]
         # We want multiple maps simultaneously
-        uu = "/%s/%s" % (getattr(self.repl, "_global_token", ""),
+        uu = "/%s/%s" % (self._global_token,
                         str(uuid.uuid1()).replace("-","_"))
         from .pannable_map import PannableMapServer
         data = widget.data_source


diff -r 71ceede82775407793c71670ae2a5f063ff68aa4 -r fdc44a69a4814a753dd1b7e9a738a8f1c99bba33 yt/utilities/command_line.py
--- a/yt/utilities/command_line.py
+++ b/yt/utilities/command_line.py
@@ -1276,6 +1276,9 @@
             dict(short="-d", long="--debug", action="store_true",
                  default = False, dest="debug",
                  help="Add a debugging mode for cell execution"),
+            dict(short = "-r", long = "--remote", action = "store_true",
+                 default = False, dest="use_pyro",
+                 help = "Use with a remote Pyro4 server."),
             "opf"
             )
     description = \
@@ -1307,20 +1310,26 @@
             except ValueError:
                 print "Please try a number next time."
                 return 1
-        base_extjs_path = os.path.join(os.environ["YT_DEST"], "src")
-        if not os.path.isfile(os.path.join(base_extjs_path, "ext-resources", "ext-all.js")):
+        fn = "reason-js-20120623.zip"
+        reasonjs_path = os.path.join(os.environ["YT_DEST"], "src", fn)
+        if not os.path.isfile(reasonjs_path):
             print
-            print "*** You are missing the ExtJS support files. You  ***"
+            print "*** You are missing the Reason support files. You ***"
             print "*** You can get these by either rerunning the     ***"
             print "*** install script installing, or downloading     ***"
             print "*** them manually.                                ***"
+            print "***                                               ***"
+            print "*** FOR INSTANCE:                                 ***"
+            print
+            print "cd %s" % os.path.join(os.environ["YT_DEST"], "src")
+            print "wget http://yt-project.org/dependencies/reason-js-20120623.zip"
             print
             sys.exit(1)
         from yt.config import ytcfg;ytcfg["yt","__withinreason"]="True"
         import yt.utilities.bottle as bottle
         from yt.gui.reason.extdirect_repl import ExtDirectREPL
         from yt.gui.reason.bottle_mods import uuid_serve_functions, PayloadHandler
-        hr = ExtDirectREPL(base_extjs_path)
+        hr = ExtDirectREPL(reasonjs_path, use_pyro=args.use_pyro)
         hr.debug = PayloadHandler.debug = args.debug
         command_line = ["pfs = []"]
         if args.find:



https://bitbucket.org/yt_analysis/yt/changeset/4af7010eb6bc/
changeset:   4af7010eb6bc
branch:      yt
user:        ngoldbaum
date:        2012-06-25 23:40:03
summary:     Merging
affected #:  163 files
Diff too large to display.

https://bitbucket.org/yt_analysis/yt/changeset/e89e03aa8d40/
changeset:   e89e03aa8d40
branch:      yt
user:        ngoldbaum
date:        2012-06-27 05:52:41
summary:     Merging.
affected #:  4 files

diff -r 4af7010eb6bc30c097f3ed3a6bc4c6c1aa12c917 -r e89e03aa8d402e208cafad696091820527ad49be yt/data_objects/data_containers.py
--- a/yt/data_objects/data_containers.py
+++ b/yt/data_objects/data_containers.py
@@ -1586,7 +1586,7 @@
     def __init__(self, axis, field, weight_field = None,
                  max_level = None, center = None, pf = None,
                  source=None, node_name = None, field_cuts = None,
-                 preload_style='level', serialize=True,
+                 preload_style=None, serialize=True,
                  style = "integrate", **kwargs):
         """
         This is a data object corresponding to a line integral through the
@@ -1634,9 +1634,9 @@
             region of a grid out.  They can be of the form "grid['Temperature']
             > 100" for instance.
         preload_style : string
-            Either 'level' (default) or 'all'.  Defines how grids are loaded --
-            either level by level, or all at once.  Only applicable during
-            parallel runs.
+            Either 'level', 'all', or None (default).  Defines how grids are
+            loaded -- either level by level, or all at once.  Only applicable
+            during parallel runs.
         serialize : bool, optional
             Whether we should store this projection in the .yt file or not.
         kwargs : dict of items
@@ -1763,11 +1763,20 @@
         # Note that this will briefly double RAM usage
         if self.proj_style == "mip":
             merge_style = -1
+            op = "max"
         elif self.proj_style == "integrate":
             merge_style = 1
+            op = "sum"
         else:
             raise NotImplementedError
-        tree = self.comm.merge_quadtree_buffers(tree, merge_style=merge_style)
+        #tree = self.comm.merge_quadtree_buffers(tree, merge_style=merge_style)
+        buf = list(tree.tobuffer())
+        del tree
+        new_buf = [buf.pop(0)]
+        new_buf.append(self.comm.mpi_allreduce(buf.pop(0), op=op))
+        new_buf.append(self.comm.mpi_allreduce(buf.pop(0), op=op))
+        tree = self._get_tree(len(fields))
+        tree.frombuffer(new_buf[0], new_buf[1], new_buf[2], merge_style)
         coord_data, field_data, weight_data, dxs = [], [], [], []
         for level in range(0, self._max_level + 1):
             npos, nvals, nwvals = tree.get_all_from_level(level, False)
@@ -1810,7 +1819,7 @@
 
     def _add_grid_to_tree(self, tree, grid, fields, zero_out, dls):
         # We build up the fields to add
-        if self._weight is None:
+        if self._weight is None or fields is None:
             weight_data = na.ones(grid.ActiveDimensions, dtype='float64')
             if zero_out: weight_data[grid.child_indices] = 0
             masked_data = [fd.astype('float64') * weight_data
@@ -1831,7 +1840,7 @@
         weight_proj = self.func(weight_data, axis=self.axis) * wdl
         if (self._check_region and not self.source._is_fully_enclosed(grid)) or self._field_cuts is not None:
             used_data = self._get_points_in_region(grid).astype('bool')
-            used_points = na.where(na.logical_or.reduce(used_data, self.axis))
+            used_points = na.logical_or.reduce(used_data, self.axis)
         else:
             used_data = na.array([1.0], dtype='bool')
             used_points = slice(None)
@@ -1847,16 +1856,33 @@
     def _add_level_to_tree(self, tree, level, fields):
         grids_to_project = [g for g in self._get_grid_objs()
                             if g.Level == level]
-        if len(grids_to_project) == 0: return
-        dls, convs = self._get_dls(grids_to_project[0], fields)
+        grids_to_initialize = [g for g in self._grids if (g.Level == level)]
         zero_out = (level != self._max_level)
-        pbar = get_pbar('Projecting  level % 2i / % 2i ' \
-                          % (level, self._max_level), len(grids_to_project))
-        for pi, grid in enumerate(grids_to_project):
-            self._add_grid_to_tree(tree, grid, fields, zero_out, dls)
+        if len(grids_to_initialize) == 0: return
+        pbar = get_pbar('Initializing tree % 2i / % 2i' \
+                          % (level, self._max_level), len(grids_to_initialize))
+        start_index = na.empty(2, dtype="int64")
+        dims = na.empty(2, dtype="int64")
+        xax = x_dict[self.axis]
+        yax = y_dict[self.axis]
+        for pi, grid in enumerate(grids_to_initialize):
+            dims[0] = grid.ActiveDimensions[xax]
+            dims[1] = grid.ActiveDimensions[yax]
+            ind = grid.get_global_startindex()
+            start_index[0] = ind[xax]
+            start_index[1] = ind[yax]
+            tree.initialize_grid(level, start_index, dims)
             pbar.update(pi)
-            grid.clear_data()
         pbar.finish()
+        if len(grids_to_project) > 0:
+            dls, convs = self._get_dls(grids_to_project[0], fields)
+            pbar = get_pbar('Projecting  level % 2i / % 2i ' \
+                              % (level, self._max_level), len(grids_to_project))
+            for pi, grid in enumerate(grids_to_project):
+                self._add_grid_to_tree(tree, grid, fields, zero_out, dls)
+                pbar.update(pi)
+                grid.clear_data()
+            pbar.finish()
         return
 
     def _get_points_in_region(self, grid):


diff -r 4af7010eb6bc30c097f3ed3a6bc4c6c1aa12c917 -r e89e03aa8d402e208cafad696091820527ad49be yt/data_objects/grid_patch.py
--- a/yt/data_objects/grid_patch.py
+++ b/yt/data_objects/grid_patch.py
@@ -144,7 +144,7 @@
             else:
                 self[field] = self.pf.field_info[field](self)
         else: # Can't find the field, try as it might
-            raise exceptions.KeyError, field
+            raise exceptions.KeyError(field)
 
     def has_key(self, key):
         return (key in self.field_data)


diff -r 4af7010eb6bc30c097f3ed3a6bc4c6c1aa12c917 -r e89e03aa8d402e208cafad696091820527ad49be yt/utilities/lib/QuadTree.pyx
--- a/yt/utilities/lib/QuadTree.pyx
+++ b/yt/utilities/lib/QuadTree.pyx
@@ -251,7 +251,7 @@
     cdef void add_to_position(self,
                  int level, np.int64_t pos[2],
                  np.float64_t *val,
-                 np.float64_t weight_val):
+                 np.float64_t weight_val, skip = 0):
         cdef int i, j, L
         cdef QuadTreeNode *node
         node = self.find_on_root_level(pos, level)
@@ -265,6 +265,7 @@
             i = (pos[0] >= fac*(2*node.pos[0]+1))
             j = (pos[1] >= fac*(2*node.pos[1]+1))
             node = node.children[i][j]
+        if skip == 1: return
         self.combine(node, val, weight_val, self.nvals)
             
     @cython.cdivision(True)
@@ -276,14 +277,14 @@
         j = <np.int64_t> (pos[1] / self.po2[level])
         return self.root_nodes[i][j]
         
-    
     @cython.boundscheck(False)
     @cython.wraparound(False)
     def add_array_to_tree(self, int level,
             np.ndarray[np.int64_t, ndim=1] pxs,
             np.ndarray[np.int64_t, ndim=1] pys,
             np.ndarray[np.float64_t, ndim=2] pvals,
-            np.ndarray[np.float64_t, ndim=1] pweight_vals):
+            np.ndarray[np.float64_t, ndim=1] pweight_vals,
+            int skip = 0):
         cdef int np = pxs.shape[0]
         cdef int p
         cdef cnp.float64_t *vals
@@ -293,15 +294,22 @@
             vals = data + self.nvals*p
             pos[0] = pxs[p]
             pos[1] = pys[p]
-            self.add_to_position(level, pos, vals, pweight_vals[p])
+            self.add_to_position(level, pos, vals, pweight_vals[p], skip)
         return
 
-    def add_grid_to_tree(self, int level,
-                         np.ndarray[np.int64_t, ndim=1] start_index,
-                         np.ndarray[np.float64_t, ndim=2] pvals,
-                         np.ndarray[np.float64_t, ndim=2] wvals,
-                         np.ndarray[np.int32_t, ndim=2] cm):
-        pass
+    @cython.boundscheck(False)
+    @cython.wraparound(False)
+    def initialize_grid(self, int level,
+                        cnp.ndarray[np.int64_t, ndim=1] start_index, 
+                        cnp.ndarray[np.int64_t, ndim=1] dims):
+        # We assume that start_index is indices 0 and 1 of ourself
+        cdef int i, j
+        cdef cnp.int64_t pos[2]
+        for i in range(dims[0]):
+            pos[0] = i + start_index[0]
+            for j in range(dims[1]):
+                pos[1] = j + start_index[1]
+                self.add_to_position(level, pos, NULL, 0.0, 1)
 
     @cython.boundscheck(False)
     @cython.wraparound(False)


diff -r 4af7010eb6bc30c097f3ed3a6bc4c6c1aa12c917 -r e89e03aa8d402e208cafad696091820527ad49be yt/utilities/parallel_tools/parallel_analysis_interface.py
--- a/yt/utilities/parallel_tools/parallel_analysis_interface.py
+++ b/yt/utilities/parallel_tools/parallel_analysis_interface.py
@@ -709,6 +709,10 @@
 
         mask = 1
 
+        buf = qt.tobuffer()
+        print "PROC", rank, buf[0].shape, buf[1].shape, buf[2].shape
+        sys.exit()
+
         args = qt.get_args() # Will always be the same
         tgd = na.array([args[0], args[1]], dtype='int64')
         sizebuf = na.zeros(1, 'int64')



https://bitbucket.org/yt_analysis/yt/changeset/d8f3b87cf52f/
changeset:   d8f3b87cf52f
branch:      yt
user:        ngoldbaum
date:        2012-06-27 06:19:51
summary:     Adding docstrings for the new plotting functions.
affected #:  1 file

diff -r e89e03aa8d402e208cafad696091820527ad49be -r d8f3b87cf52f761da9568c4a2ba156c0414b6a1b yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -93,17 +93,182 @@
 linear_transform = FieldTransform('linear', lambda x: x, LinearLocator())
 
 def SlicePlot(pf, axis, fields, center=None, width=None, origin='center-window'):
+    r"""
+    SlicePlot(pf, axis, fields, center=None, width=None, origin='center-window')
+
+    Given a pf object, an axis to slice along, and a field name
+    string, this will return a PWViewrMPL object containing
+    the plot.
+
+    The plot can be updated using one of the many helper functions
+    defined in PlotWindow.
+
+    Parameters
+    ----------
+    pf : :class:`yt.data_objects.apy.StaticOutput`
+
+        This is the parameter file object corresponding to the
+        simulation output to be plotted.
+
+    axis : int
+
+         An int corresponding to the axis to slice along.  
+	 (0 : x, 1 : y, 2 : z)
+
+    fields : string
+    
+          The name of the field(s) to be plotted.
+
+    center : A two or three-element vector of sequence floats, 'c', or
+             'center'
+
+           The coordinate of the center of the image.  If left blanck,
+           the image centers on the location of the maximum density
+           cell.  If set to 'c' or 'center', the plot is centered on
+           the middle of the domain.
+
+    width : A tuple or a float
+    
+           A tuple containing the width of image and the string key of
+           the unit: (width, 'unit').  If set to a float, code units
+           are assumed
+
+    origin : A string
+
+            The location of the origin of the plot coordinate system.
+            Currently, can be set to three options:
+
+	    'left-domain':
+	         The bottom-left hand corner of the simulation domain.
+
+            'left-window':
+	         The bottom-left hand cordiner of the plot window.
+
+	    'center-window'
+	         The center of the plot window.
+
+    """
     (bounds,center) = GetBoundsAndCenter(axis,center,width,pf)
     slice = pf.h.slice(axis,center[axis],fields=fields)
     return PWViewerMPL(slice,bounds,origin=origin)
 
 def ProjectionPlot(pf, axis, fields, center=None, width=None,
                    weight_field=None, max_level=None, origin='center-window'):
+    r"""
+    ProjectionPlot(pf, axis, fields, center=None, width=None, 
+                   weight_field=None, max_level=None, origin='center-window')
+
+    Given a pf object, an axis to project along, and a field name
+    string, this will return a PWViewrMPL object containing
+    the plot.
+
+    The plot can be updated using one of the many helper functions
+    defined in PlotWindow.
+
+    Parameters
+    ----------
+    pf : :class:`yt.data_objects.apy.StaticOutput`
+
+        This is the parameter file object corresponding to the
+        simulation output to be plotted.
+
+    axis : int
+
+         An int corresponding to the axis to project along.  
+	 (0 : x, 1 : y, 2 : z)
+
+    fields : string
+    
+          The name of the field(s) to be plotted.
+
+    center : A two or three-element vector of sequence floats, 'c', or
+             'center'
+
+           The coordinate of the center of the image.  If left blanck,
+           the image centers on the location of the maximum density
+           cell.  If set to 'c' or 'center', the plot is centered on
+           the middle of the domain.
+
+    width : A tuple or a float
+    
+           A tuple containing the width of image and the string key of
+           the unit: (width, 'unit').  If set to a float, code units
+           are assumed
+
+    weight_field : string
+
+            The name of the weighting field.  Set to None for no weight.
+
+    max_level: int
+
+            The maximum level to project to.
+            
+    origin : string
+
+            The location of the origin of the plot coordinate system.
+            Currently, can be set to three options:
+
+	    'left-domain':
+	         The bottom-left hand corner of the simulation domain.
+
+            'left-window':
+	         The bottom-left hand cordiner of the plot window.
+
+	    'center-window'
+	         The center of the plot window.
+
+    """
     (bounds,center) = GetBoundsAndCenter(axis,center,width,pf)
     proj = pf.h.proj(axis,fields,weight_field=weight_field,max_level=max_level,center=center)
     return PWViewerMPL(proj,bounds,origin=origin)
 
 def OffAxisSlicePlot(pf, normal, fields, center=None, width=None, north_vector=None):
+    r"""
+    SlicePlot(pf, normal, fields, center=None, width=None, north_vector=None)
+
+    Given a pf object, a normal vector defining a slicing plonae, and
+    a field name string, this will return a PWViewrMPL object
+    containing the plot.
+
+    The plot can be updated using one of the many helper functions
+    defined in PlotWindow.
+
+    Parameters
+    ----------
+    pf : :class:`yt.data_objects.apy.StaticOutput`
+
+        This is the parameter file object corresponding to the
+        simulation output to be plotted.
+
+    normal : a sequence of floats
+
+         The vector normal to the slicing plane.
+
+    fields : string
+    
+          The name of the field(s) to be plotted.
+
+    center : A two or three-element vector of sequence floats, 'c', or
+             'center'
+
+           The coordinate of the center of the image.  If left blanck,
+           the image centers on the location of the maximum density
+           cell.  If set to 'c' or 'center', the plot is centered on
+           the middle of the domain.
+
+    width : A tuple or a float
+    
+           A tuple containing the width of image and the string key of
+           the unit: (width, 'unit').  If set to a float, code units
+           are assumed
+
+    north-vector : a sequence of floats
+    
+           A vector defining the 'up' direction in the plot.  This
+           option sets the orientation of the slicing plane.  If not
+           set, an arbitrary grid-aligned north-vector is chosen.
+
+    """
     (bounds,center_rot) = GetOffAxisBoundsAndCenter(normal,center,width,pf)
     cutting = pf.h.cutting(normal,center,fields=fields,north_vector=north_vector)
     # Hard-coding the origin keyword since the other two options

Repository URL: https://bitbucket.org/yt_analysis/yt/

--

This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.



More information about the yt-svn mailing list