## page was renamed from Cytoscape_3.0/MiniRetreatTwo = Mini-Retreat Two = * November 14-15, 2008 * Genentech Hall, 4th floor, [[http://pub.ucsf.edu/missionbay/|UCSF Mission Bay]], 600 16th St. San Francisco, CA 94158 * Alex's cell: 415-328-3967 == Logistics == * Flights: arrive Thursday night, depart Saturday evening * The Official Hotel! * The Queen Anne is particularly recommended [[http://www.queenanne.com/]] ($125; It's not close by, however. We would have to organize pick ups/ drop offs)[[http://channels.isp.netscape.com/whatsnew/package.jsp?name=fte/bedbugs/bedbugs&floc=wn-nx|Check for bed bugs]]! Ask for the UCSF group rate! * Transportation: You can take [[http://www.bart.gov/guide/airport/inbound_sfo.aspx|BART]] to and from the SFO airport. And there is the [[http://transit.511.org/schedules/index.aspx#m1=S&m2=rail&routeid=26606&cid=SF|K/T-line train]] that connects downtown SF to the campus (takes ~20min). If you are staying at the Queen Anne check out [[http://www.queenanne.com/resources/transport.html|this shuttle]]. * Schedule: THUR - nothing planned; FRI - all day meeting, breakfast and lunch on campus, dinner reservations for 6:30PM at [[http://www.kohsamuiandthemonkey.com/dinner_menu.htm|Kohsamui & The Monkey (thai)]] ; SAT - pastries and coffee provided in the morning, lunch on campus. * We'll be on skype... and email, of course. == Topics for Discussion == * View''''''Model * How does this relate to widely diverse presentation use cases 1. lightweight web rendering 1. use of Cytoscape model components in other systems/products without view * Daniel's pluggable renderers * Questions for Daniel: 1. What are the possible memory costs for having pluggable renderers (not detailed -- approximate)? 1. What are the performance implications? 1. How do we serialize these? * My (DanielAbel) notes are at DanielAbel/PluggableRenderers which discusses these issues a bit. * Begin Presentation API * UI Events and how they interact with Cytoscape Events * Work Layer (Command, Tunables) * some of my questions and ideas: [[Cytoscape_3.0/MiniRetreatTwo/DanielsQuestions]] (DanielAbel) === Agenda === ==== Friday ==== 9:15AM - 6:00PM (''Note:'' ISB group can't stay for Saturday, need view model nailed down and some talk about the web stuff) * View Model * Discussion of web-capability * Presentation ==== Saturday ==== 9:30AM - 3:00PM * Renderers * UI Events * CyDataTables higher order semantics / operations (JOIN, etc) == Goal == * Finish the View''''''Model == Pre-meeting Comments == * Should vizmapper and editor be covered at this meeting or is this for a later meeting? ''->later'' == Decisions and Results == This is an attempt pull together the major decisions we made and (possibly) the areas where we might need further discussion (perhaps via E-Mail). === Architecture === * I think this may be redundant, but there were a couple of architectural principles that were stated (for which there was agreement) but which might not be documented elsewhere. Looking at the rough layering described below (See Day 1, review of architecture) there was a principle that interaction between an upper layer and a lower layer would be using method calls, and that interaction between a lower layer and an upper layer was with events. Note that for these purposes, the I/O layer can be considered to be at the same level as View Model, Presentation, and Model (that is, it might call methods in any of those, but will probably not listen for events from any of those). This becomes important in some of our decisions. * This was discucssed here: [[Cytoscape_3.0/DesignGuidelines]] * We also realized that there were View Model and Presentation layers for the CyDataTables sections of the model as well as the CyNetwork sections. This turns out to be very powerful, and may be one of the ways we can support advanced visualizations such as heatmaps, histograms, charts, etc. === Model === * We had a long discussion about the need to support annotations (decorations) in a principled way. I believe we reached consensus that the right approach to this was to extend CyRootNetwork to a CyDecoratedRootNetwork. This would add a new type of BaseNetwork that includes all of the Decorations and Connectors (which are extensions of CyNode and CyEdge, respectively). As with metanodes and hierarchical networks, most plugins/algorithms would get the BaseNetwork, which does not include any metanodes, decorations, or connections. Only plugins that really cared about decorations would need to know how to deal with a CyDecoratedRootNetwork and the DecoratedBaseNetwork. The View Model could treat all Decorations and nodes and all Connectors as special cases of Nodes and Edges for which there might be special Renderer's for (e.g. the SVG Decoration Renderer). * Once resolving the approach, we all agreed that implementation of this was a lower priority than the many other things that need to get done for 3.0. === View Model === * The View Model maintains the ''visual state'' of the model (network or table) -- essentially a set of VisualProperties for each object (CyNetwork, CyNode, CyEdge, CyDataTable, CyRow, CyColumn [do we need a CyColumn? I think we're going to need a CyColumnView, so maybe we do have a CyColumn that is nothing more than an Identifiable and a column name]). * There was general enthusiasm for Daniel's pluggable renderers, which would provide the list of visual attributes to the VizMapper for the user to select from. * In order to preserve more complicated selections across session loads/saves, we agreed that the VisualProperties defined at session load time would be preserved unless explicitly reset by the user/application. This does not mean that the current set of renderers will support them. * Generally the list of renderers and properties supported by those renderers would flow from the presentation layer to the VizMap UI (we didn't discuss a specific API for that) and would be provided to the VizMap via a method. * There was general agreement (although not unanimous) that we would need to preserve the ability for a user (or a plugin, which is where the disagreement comes) to override the VizMapper. This means that we need to be able to set a VisualProperty as overridden (or immutable) so that the VizMapper does not wipe out user customizations. * For "selection", we realized that there were two concepts being conflated. The first is a visual designation of a group of nodes and edges to provide feedback to the user. The second is the need to create (and record) a set of nodes or edges for the purpose of limiting operations or other purposes. The current favored option for handling this is to support the idea of subsets. The current proposal is to add methods: * createNodeSubset(List list); * createNodeSubset(String name, List list); * createEdgeSubset(List list); * createEdgeSubset(String name, List list); * ListgetNodeSubset(); * ListgetNodeSubset(String name); * ... etc ... [I wonder if it might be better to create subsets of Views: createSubset(List list), etc. This would require the createSubset methods to be a little intelligent about the default subsets.] While this is the current proposal, some discomfort remained. * One new requirement we realized is that we need to explicitly support z-order (layers) in the View Model. This resolves a number of problems and work-arounds that we currently see in our code base. Once we define layers, we get lots of possibilities for nice user interfaces that leverage users' experience with Photoshop, etc. We also get some kinds of graphical group manipulation for free (by turning layers on and off). [NOTE: there was lots of discussion about x,y,z and some of the performance issues surrounding settings x,y, and z through VisualProperties and the fact that (in general) you would not ever actually map those values with the VizMapper. We never reached a consensus, but for background people should read Daniel's discussion of CyGeometry (or maybe we just use Point3d from the javax.vecmath, which has lots of nice capabilities)]. === Presentation === * In general, the Presentation API is a very thin layer. It is up to the Application to pass the appropriate context when the presentation is instantiated (e.g. the JComponent). * The presentation must support getNetworkView, draw, update, fitContent, and fitSubset. === Events === list of events moved to [[Cytoscape_3.0/EventHandling/PlannedCoreEventsIn3.0]] == Meeting Notes == === Day 1 === Review of architecture: (photo will be attached) * UI - Swing, headless * Application - will be thin layers with a bunch of Swing code to handle GUI or cmd line input * Work - * I/O - * View Model - State (color), Selection/Highlighting, Hide/Restore, Layout coordinates, supports serialization * Presentation - * Model - Examples: * Layouts/Tunables - UI is inferred (Swing or cmd line) * MCode - can switch to Tunables? Pros and cons. * Selection:view - UI selection of graphics with visual feedback * Selection:subsets - selection gets passed to model * Presentation-based selection - presentation fires selection event, application listens, application tells View Model to define subset (a list that can be serialized), then Presentation layers can respond to subsets Questions: * Will the plugin dev have to write multiple UIs for each display type (Swing, web, cmd)? Will Tunables suffice for plugins? Or, should we have an abstract UI layer that handles a broader set of UI elements for the diverse front-ends. * What exactly is the definition of the web front-end? This will influence how we design the back-end. * Does selection happen in Model? * Could the View Model be absorbed by the Model as namespaces? * Do we need to be more generic than "subset", to support other attributes at the View Model layer? ---- VizMap: * Visual Style - define Visual Property mappings, serializable, sits in VizMap * Mapping Calculator - given a View Model and Attributes, it tells you how to map; one calculator per attribute, provided when created; get/set attrName, Visual Property, apply(view) * Can you get at a discrete or continuous mapper from cmd line? Too much of the control is in the VizMap UI. This needs to be made public in order to support headless Visual Style creation. * Start up renderer; renderer provides list of Visual Properties into the VizMap UI to appropriately restrict * Does Renderer handle x,y,z? Are they Visual Properties? * User space: arbitrary coord system, +/- infinity * Device space: * Even headless mode has a renderer, e.g., for pdf export. A basic renderer can handle x,y,z for headless. * Layout sets coords by setting Visual Properties. The default renderer will provide the basic, core set of Visual Properties. * Where are these canonical VPs stored and how does the end user access these? * Should be able to query renderer on what is supported AND should be able to access canonical set of VPs. * Store immutable status of a VP in View Model so it is not overwritten by VizMap. * Node renderers are mapped by VizMap via attributes per node; the node renderer will determine which VPs are available in the UI. ---- Web presentation strategy: * Functionality could be handled by JSON, passed back and forth between a web client and an Work layer. JSON (javascript object notation) provides a way to pass data structures as objects, like Perl's structures, e.g., Hashes of Hashes of Arrays. * Node context menu, search, add node ---- Presentation Layer: * Current methods in Graph View need to be split into View Model, Presentation, Renderers: * background, zoom, getCenter - VM * layers? * get/set node/edge views; ditch iterators? - VM * selection; ditch enable/disable in interface? - VM * hide/show view objects - VM * fitContent - P * updateView - P * fitSelected - P * setGraphLOD - R * getComponent, getContainer -> drawViewGraph - P, then events are interpreted by Application. When/how does presentation get its context? At instantiation? Or, subclass? The Swing subclass impl could have a more complex drawViewGraph or at instatiation to take in the context, JComponent. * printing - P. It's really just another Presentation derived from View Model. * Presentation: getNetworkView, draw, update, fitContent, fitSubset * Should Presentation listen for View Model changes? Or, should the View Model be listening and then call Presentation.update? * Should consider having special cases for setting x,y,z Visual Properties to improve performance on move events. We don't want to open the door to having a bunch of special sets, but this case is isolated. Ultimately, we should benchmark this option and see if the performance gains are significance. * UI events (click, double-click, etc). Presentation needs to fire those events. Application listens, interprets and calls methods in View Model. These are Cytoscape "clicks" not low-leve swing events. * EventConsumers must be resolved for one-to-one mapping with functionality. If two plugins both consume double-click, the user will have to pick one. EventListeners, on the other hand, can co-exist, no problem. How do we want to share clicks? How do we want users to choose? * Layers & Annotations: * We need z-order in the View Model. * Do we still need layers? * We allow in the View Model, describe node shape by SVG? * Can we shoe-horn annotations into nodes? * Should they be put into a subnetwork separate from CyNetwork? * Should we super class node to Shape and have nodes and annotations? Create an Annotation class? Or just have annotations be nodes? * EdgeViews, NodeViews, and Identifiables are basically the same. Maybe CyDecoration should extend Identifiable. * Should there be a getViews() that gets Nodes, Edges, and Annotations? Then getSUID will also retrieve Annotations. And you can get View Events and figure out which object changed. ----- Summary: * Subset of graph objects to handle selection. View Model? * Presentation is a very thin layer. * Presentation it will get its context (e.g., JComponent) when it is instantiated by the Application * Brainstorm on Annotations --> Decorations! Tomorrow: * List of events ---- === Day 2 === While listing events below, we realized that we really need a Presentation and ViewModel for CyDataTable. This will support events in the Table, all the same events needed for Network. With proper View Model support, this doesn't even have to be table! This could be histograms and heatmaps. List of events: [[Cytoscape_3.0/EventHandling/PlannedCoreEventsIn3.0]] Need for an Action-Event Broker: * Plugin action listeners will have to be registered with the Application, along with a provided human name and description. * The user will see a pop up when then perform a gesture tied to multiple actions. * This is a new pattern for listeners. * We need to define defaults, but allow user config. But we will punt on the impl of these details until we dive into Application at a later point. Idea for Decorations: * CySubNetwork extends CyNetwork - handles metanode implementation; contains all nodes, edges, and metanodes (no decorations). * CyDecoratedNetwork extends CyNetwork - contains all nodes, edges, metanodes and decorations. * CyRootNetwork extends CyNetwork - contains everything, but can not be contained itself. * BaseNetwork extends CyRootNetwork - includes a flattened basic network of ''real'' nodes and edges (no decorations, no metanodes); ideal for graph-based analyses * BaseDecoratedNetwork extends CyRootNetwork - includes CyDecoration nodes and connectors ---- Event-coalescence optimization [[Cytoscape_3.0/MiniRetreatTwo/DanielsQuestions#head-4b142dfa6d192e4392845c4904639ac51b601b6c| Daniels Starter Questions]] * Plugin developer would set batch mode for a listener, run through events (e.g., AddNodeEvents), then declare finish. * Alternatively, we could use the Task mechanism to help control batch mode implicitly (analogous to undo). * Dragging events: when mouse-up, trigger task for updating model in batch * Event Helper would look to see if which thread we're in to decide whether to batch or not: main thread = let it pass; task thread = batch. * If you ''want'' to fire events (like in animating layouts), you run it through the main thread and it doesn't get batched. * We need a map of thread:task which will help track whether you're in a BatchTask or not. * Events within a BatchTask are checked in CyNetwork to identify the particular events that should be batched, letting "minor" events. * If Cy''''''Network/View and Cy''''''Data''''''Table/View has "batchables" with batchStart and batchEnd. Impl is in EventHelper, to '''coalesce consecutive like events'''. Alternatively, the coalescence ''could'' happen at the Model level and allow more sophisticated parsing (e.g., removing deleted nodes from an added nodes list). These coalesced events within a Batch are then run through BatchTasks per Network/View and Cy''''''Data''''''Table/View. This helps parse batches and makes use of the threading idea. * By telling CyNetwork that you want to perform a Transaction, parallel events can be excluded at the level of the network. This is a good thing. * Simple sample implementation of "batchable" idea: ''Batchable.java'' {{{ interface Batchable { void batchBegin(); void batchEnd(); } }}} ''NetworkThingy.java'' {{{ import java.util.ArrayList; import java.util.List; class NetworkThingy implements Batchable { boolean inBatch = false; List addEventList = null; List removeEventList = null; public NetworkThingy () {} public void addNetworkSubThingy (String name) { if (!inBatch) System.out.println("Added network sub-thingy "+name); else addEvent(name); } public void deleteNetworkSubThingy (String name) { if (!inBatch) System.out.println("Deleted network sub-thingy "+name); else removeEvent(name); } public void batchBegin() { inBatch = true; } public void batchEnd() { inBatch = false; if (addEventList != null && addEventList.size() > 0) { System.out.print("Added sub-thingy's "); for (String event: addEventList) { System.out.print(event+", "); } System.out.println(); } if (removeEventList != null && removeEventList.size() > 0) { System.out.print("Removed sub-thingy's "); for (String event: removeEventList) { System.out.print(event+", "); } System.out.println(); } addEventList = null; removeEventList = null; } private void addEvent(String name) { if (addEventList == null) addEventList = new ArrayList(); addEventList.add(name); } private void removeEvent(String name) { if (addEventList != null && addEventList.contains(name)) { addEventList.remove(name); return; } if (removeEventList == null) removeEventList = new ArrayList(); removeEventList.add(name); } } }}} ''TestBatch.java'' {{{ public class TestBatch { public static void main(String[] args) { NetworkThingy thingy = new NetworkThingy(); for (int i = 0; i < 100; i++) { thingy.addNetworkSubThingy("ST "+i); } thingy.batchBegin(); for (int i = 0; i < 100; i++) { thingy.addNetworkSubThingy("ST "+(i+100)); } thingy.batchEnd(); thingy = new NetworkThingy(); thingy.batchBegin(); for (int i = 0; i < 100; i++) { thingy.addNetworkSubThingy("ST "+i); } thingy.deleteNetworkSubThingy("ST 5"); thingy.deleteNetworkSubThingy("ST 50"); thingy.batchEnd(); } } }}} Alternative implementation of batchable events that switches responsibility for batching from the firing data structure to an EventHandler that manages everything. The advantages of this approach are: * The batching code, which would be redundant across all different implementations of {{{Batchable}}} from the first example, is now captured in one place. * Better separation of concerns: NetworkThingy only knows about Network things and doesn't need to worry about event handling policy. * Finer control of what gets batched. The disadvantages of this approach are: * The EventHandler must be accessible to all event listeners. * Batching is event based rather than data structure based (i.e. control is too fine grained). ''NetworkThingy.java'' {{{ class NetworkThingy { EventHandler eh; public NetworkThingy (EventHandler eh) { this.eh = eh; } public void addNetworkSubThingy (String name) { eh.fireEvent("ADD","Added network sub-thingy "+name); } public void deleteNetworkSubThingy (String name) { eh.fireEvent("DELETE","Deleted network sub-thingy "+name); } } }}} ''EventHandler.java'' {{{ import java.util.*; public class EventHandler { Map> listeners; Map> batches; public EventHandler() { listeners = new HashMap>(); batches = new HashMap>(); } public void batchBegin(String eventType) { batches.put(eventType, new ArrayList()); } public void batchEnd(String eventType) { // somehow aggregate events String aggregateEvent = "AGGREGATE:"; for (String e : batches.get(eventType)) aggregateEvent += " " + e; fireInternal(eventType,aggregateEvent); batches.remove(eventType); } public void fireEvent(String eventType, String event) { if ( batches.containsKey(eventType) ) // batching == true batches.get(eventType).add(event); else // batching == false fireInternal(eventType,event); } private void fireInternal(String eventType, String event) { List list = listeners.get(eventType); for (String l : list) System.out.println("listener: " + l + ": " + eventType + " - " + event); } public void addListener(String eventType, String listenerName) { if ( !listeners.containsKey(eventType) ) listeners.put( eventType, new ArrayList() ); listeners.get(eventType).add(listenerName); } } }}} ''TestBatch.java'' {{{ public class TestBatch { public static void main(String[] args) { EventHandler eh = new EventHandler(); eh.addListener("ADD", "homer"); eh.addListener("ADD", "marge"); eh.addListener("DELETE", "homer"); int ct = 10; NetworkThingy thingy = new NetworkThingy(eh); for (int i = 0; i < ct; i++) { thingy.addNetworkSubThingy("ST "+i); } eh.batchBegin("ADD"); for (int i = 0; i < ct; i++) { thingy.addNetworkSubThingy("ST "+(i+ct)); } eh.batchEnd("ADD"); thingy = new NetworkThingy(eh); eh.batchBegin("DELETE"); for (int i = 0; i < ct; i++) { // not being batched since we're only batching DELETE events thingy.addNetworkSubThingy("ST "+i); } thingy.deleteNetworkSubThingy("ST 5"); thingy.deleteNetworkSubThingy("ST 50"); eh.batchEnd("DELETE"); } } }}} ---- Work Layer: * Command (maybe now "Task") * getName, getDescription, execute, cancel * Your command has a set of arguments and executes. * History would be a list of all commands, and support recording * Provenance is a subset of commands ''plus'' context. Therefore, Command might not be the right level for data provenance. Data provenance helps trace path to the current data state. Useful for recreating a network, for example, from starting file, subnetwork creations, and plugin actions to the model. We need to consider the actual use case for provenance to re-analyze the requirements. * Idea: could we add pre/postProcessing hooks? * Each command/task is in a thread. * InteractiveCommand extends Command * Returns a result. Is this needed? Perhaps all Commands could return result, NULL being valid. * Monitorable - for Commands that can have a TaskMonitor * get/setTaskMonitor * TaskMonitor * getChildMonitors(array of percentages) - assigns child monitors to percent blocks (should sum to 100%). Then there could be an automatic mechanism for updating the parent by multiplying assigned percentage by progress of child. The children don't actually have to know about their parental percentages; only the parent needs to know about these in order to manage its own progress bar. * Tunables * Tunables expose the API of commands by inferring a UI in a generic way. * A command will be parameterized by Tunables. You can also pass args through a direct command call. Or call setters. The method names should match the tunable name. * We need to be able to list all commands and all tunables per command. The TunableInterceptor should be able to provide the list of tunables. * Tunables provide the equivalent of reflection, shortcutting interface development. * Should Visual Properties be handled with Tunable? ---- I/O Layer: CyReaderManager: * Should the Reader be creating the GraphView? Then loading the Presentation would depend on network size. * Readers can impl Cy''''''Network/View and Cy''''''Data''''''Table/View, e.g., xGMML Reader * Readers have to tell what objects they work with (networks, tables). CyReader: * Needs to return list of enums (supported types). Or, can pass in Class objects that are supported. Alternatively, could support isSupported methods. * Does the list of file types also come from the reader (for file chooser)? When is the ViewModel built? * By the Reader? By the ReaderManager? By the VizMap? Summary: * Multiple reader types are handled by inquiring whether a Reader supports a type. * Layouts should not be part of the Reader interface; however, layouts could potentially be passed to a Reader, isolated to a bundle. * Some Readers do not create a view (e.g., SIF Reader). * Clearly not resolved yet...