gfdnavi: its design and implementation with ajax and ruby-on-rails

52
Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails Seiya NISHIZAWA,Takeshi HORINOUCHI, Chiemi WATANABE, T. KOSHIRO, A. TOMOBAYASHI, S. OTSUKA, Y. MORIKAWA, Y.-Y. HAYASHI, M. SHIOTANI, and GFD-Dennou Davis project

Upload: caspar

Post on 07-Jan-2016

21 views

Category:

Documents


0 download

DESCRIPTION

Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails. Seiya NISHIZAWA,Takeshi HORINOUCHI, Chiemi WATANABE, T. KOSHIRO, A. TOMOBAYASHI, S. OTSUKA, Y. MORIKAWA, Y.-Y. HAYASHI, M. SHIOTANI, and GFD-Dennou Davis project. Introduction. What’s “Gfdnavi” - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

Gfdnavi:its design and implementation

with Ajax and Ruby-on-Rails

Seiya NISHIZAWA,Takeshi HORINOUCHI,Chiemi WATANABE,

T. KOSHIRO, A. TOMOBAYASHI, S. OTSUKA,Y. MORIKAWA, Y.-Y. HAYASHI, M. SHIOTANI, and

GFD-Dennou Davis project

Page 2: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

Introduction

• What’s “Gfdnavi”– A tool to archive, share, distribute, analyze, and

visualize geophysical fluid data and knowledge– desktop use to data provide server– fundamental technologies

• Ruby on Rails• GPhys

An introduction was done by T. Horinouchi yesterday.

Page 3: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

Ruby on Rails

• an open source web application framework• written in Ruby• Model-View-Controller (MVC) architecture• Convention over Configuration (CoC)• Don't repeat yourself (DRY)

• swift development– ActiveRecord– helper methods (HTML, JavaScript, ajax)

Page 4: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

ActiveRecord (AR)• a part of Rails products• a ruby implementation of the object-relational

mapping pattern

• Do not need to use SQL– For better performance, SQL can be used on AR.

node = Node.find(:first, :conditions=>[”id=?”,2]) # SELECT * FROM nodes WHERE id=2 LIMIT 1;path = node.path #=> “/samples”kas = node.keyword_attributes # SELECT * FROM keyword_attributes WHERE node_id=2;

id path parent

1 / null

2 /samples 1

id node_id keyword value

1 2 description sample directory

2 2 notice just sumple

nodes table keyword_attribute table

Page 5: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

Metadata DB

used for search

1. name-value attributes2. geospatial- and time-coordinate information3. owner, groups and access mode4. link among data5. time-stamp, size, etc

Page 6: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

1. Name-Value attributes• attributes in data file (self-describing files)

– unified access to attributes in differently formatted files with GPhys

• attributes in text file– YAML format– any name-value attributes

gphys_nc = GPhys::IO.open(“fname.nc”,”T”) # NetCDFgphys_nc.att_names #=> [“long_name”, …]gphys_nc.get_att(“standard_name”) #=> “air_temperature”

gphys_grib = GPhys::IO.open(“fname.grib”, “TMP”) # GRIBgphys_grib .att_names #=> [“long_name”, …]gphys_grib.get_att(“standard_name”) #=> ”air_temperatrue”

description: NCEP/NCAR reanalysisgfdnavi: owner: user1 other_mode: 0 rgroups: - groupA - groupB

Page 7: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

YAML

• a human-readable data serialization format– easier to read/write than XML

puts “Array (list)”ary = [0,1,2]puts ary.to_yaml

puts “\nHash (associative array)”hash = {“key0”=>”value0”, ”key1”=>”value1”}puts hash.to_yaml

Array (list)---- 0- 1- 2

Hash (associative array)---key1: value0key0: value1

Back

Page 8: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

2. Geospatial- and time-coordinate information– spatial region

• rectangle in longitude-latitude section

– temporal region• start time and end time

global, regional, or point swath

Page 9: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

3. Owner, Groups, and Access mode– permission system like i-node

• readable and writable for groups and others

– Multiple groups are allowed.

4. Link among data– e.g. This data was calculated from these variables

Page 10: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

Directory tree structure• nodes in the tree structure

– node types: directories, variables, images, knowledges, etc

• Each node can have some metadata.– inherited to children nodes

local or opendap directoriesdata files

variables

image files

attributesdescription = “……..”owner = userAgroups = [groupA,groupB]

description = “……..”param1 = value1param2 = [value21,value22]

attributesgroups

virtual aggregated files

Page 11: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

fork a child process

Analysis model

open data file(s)

calculate draw

NetCDF PNG

analysis

draw

storage

GPhysDB

cached get cache

output output

cache

yes

no

programmable

Analysis and Visualization

Page 12: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

• Analysis model (Analysis class)– all the parameters for analysis or visualization

• the form in the analysis page• instance variables of the Analysis object

It is able to construct one from the other• enable to reconstruct the analysis page from

• drawn image• history list

Page 13: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

• Draw method and analysis function are not hard-coded.– Their definitions are in YAML files (editable)

• one method in one file

:name: spectrum:description: |FFT|^2 along a specific dimension:nvars: 1:script: | [gphys0.fft(*arg0).abs ** 2]

:arguments:- :description: the dimensions for spectrum :value_type: array_string :default: []

spectrum.yml

simple coding due to GPhys

can create and modifyvia web-browser

Page 14: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

• examples of original draw methods in a Gfdnavi server providing an ensemble forecast data

Page 15: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

User Interface

• bottleneck of network application– network bandwidth– machine power and system load of the server

• better usability– ajax

• Rails has many helper methods to write HTML and JavaScript to use ajax.

– cache

Page 16: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

• Animation

Page 17: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

Web service• local programming• cross-site use

– other Gfdnavi servers– non-Gfdnavi servers

SOAPAPIs for all the analysis functions and draw methods

use the Analysis classWSDL

(REST)

Page 18: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

Summary• Metadata and Directory tree structure

– attributes in self-describing data files and YAML files– inheritanceunified access to attributes with GPhyseasy and swift development with AcriveRecord (Rails)

• Analysis/Visualization– programmable (with text editor or web-browser)easy and extensible coding with GPhys

• User Interface– good usability with ajax and cacheeasy development with helper methods (Rails)

Page 19: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

Thank you

Page 20: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails
Page 21: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

MVC architecture• Model

– Relational Database• ActiveRecord: a ruby object that wraps a row in a

database table

• View– HTML

• ERuby: a templating system that embeds Ruby into a text document

– JavaScript• ajax

• Controller

Page 22: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

Web server

Web server

G

Controller

Model

ActiveRecord, VizShot

View

ERubyhelper methods

User

Web Browser

RDB

create, update, deleteanalysis, draw

request

HTMLJavaScript

Gfdnavi server

GPhysDCL

Page 23: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails
Page 24: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

ActiveRecord (AR)• a part of Rails products• a ruby implementation of the object-relational

mapping pattern– a row in a table ↔ an instance object– a column ↔ an instance method– a reference between tables ↔ an instance method

part = Part.newpart.name = “Sample part”part.price = 123.45part.save

INSERT INTO parts (name, price) \ values (‘Sample part’, 123.45);

name = “gearbox”part = Part.find(:first, :conditions=>[“name=?”,name])

SELECT * FROM parts \ WHERE name=‘gearbox’ LIMIT 1;

Page 25: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

RDB tables

• Directory tree structure– nodes (basic unit of a tree)

• directories, variables, images, knowledges, etc.

• Meta data– keyword_attributes– spatial_and_temporal_attributes– node_relations

• User’s information– users– groups

Page 26: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

• instance method is used for reference between two tables with foreign key

class Cart < AcriveRecord::Base has_many :itemsend

class Item < AcriveRecord::Base belongs_to :cartend

id cart_id name amount

1 1 orange 3

2 1 apple 2

id user

1 userA

cart = Cart.find_by_user(“userA”) #=> cart whose # user = “userA”items = cart.items #=> array of # items whose cart_id = 1items[0].name #=> “orenge”items[1].amount #=> 2

carts items

Page 27: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

Directory tree structure• Tree structure is good way to organize data

/…/data_top_dir/ncep.yml /ncep/UV.jan.nc (contains U and V) /UV_500hPa_vect.png /UV.jan.nc.SIGEN /UV_500hPa_vect.png.yml

id path name parent node_type

1 / / null directory

2 /ncep ncep 1 directory

3 /ncep/UV.jan.nc UV.jan.nc 2 directory

4 /ncep/UV.jan.nc/U U 3 variable

5 /ncep/UV.jan.nc/V V 3 variable

6 /ncep/UV_500hPa_vect.png UV_500hPa_vect.png 3 image

Page 28: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

• acts_as_tree method of AR– “parent” column is assumed to have parent’s “id”– “parent” method return the parent node– “children” method return the array of children nodes

class Node < AcriveRecord::Base acts_as_treeend

node = Node.find(3) #=> node whose id=3node.children #=> array of nodes # whose parent column is 3node.parent #=> node whose id is value of parent column

Page 29: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

• two types of meta data1. meta data in data file (self-describing file)

• NetCDF: variable attributes

variables: float U(level,lat,lon) ; U:long_name = “zonal velocity“ ; U:units = “m/s” ; U:missing_value = -999.f ; U:standard_name = “eastward_wind” ; U:statistic = “Long Term Mean\n” ; float V(level,lat,lon) ; V:long_name = “meridional velocity” ; V:units = “m/s” ; V:missing_value = -999.f ; V:standard_name = “northward wind” ; V:statistic = “Long Term Mean\n” ; float lon(lon) ; : snip

Page 30: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

2. meta data in YAML and SIGEN files• ncep.yml

• UV_500hPa_vect.png.yml

description: vector plot of horizontal velocity at 500hPagfdnavi: owner: user2 references: - /ncep/UV.jan.nc/U - /ncep/UV.jan.nc/V other_mode: 0 rgroups: - groupA

description: NCEP/NCAR reanalysisgfdnavi: owner: user1 other_mode: 0 rgroups: - groupA - groupB

Page 31: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

• keyword_attributes tableid node_id keyword num_value value

1 2 description NCEP/NCAR reanalysis

2 3 description horizontal velocity in January

3 4 long_name zonal velocity

4 4 units m/s

5 4 missing_value -999.0

6 4 standard_name

eastward wind

7 4 statistic Long Term Mean\n

8 5 long_name meridional velocity

9 5 units m/s

10 5 missing_value -999.0

11 5 standard_name

northward wind

12 5 statistic Long Term Mean\n

13 6 description vector plot of horizontal velocity at 500hPa

Page 32: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

• spatial_and_temporal_attributes table

• node_relations table– UV_500hPa_vect.png (node id = 6) was drawn

from U (node id=4) and V (node id = 5)

id reference referenced_by title

1 4 6 drawn

2 5 6 drawn

id node_id lon_lb lon_rt lat_lb lat_rt starttime endtime

1 4 0 360 -90 90 2008-01-01-00:00 2008-01-31-18:00

2 5 0 360 -90 90 2008-01-01-00:00 2008-01-31-18:00

Page 33: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

• user and groups– root, user1(groupA,groupB), user2(groupA), user3

• access permission– owner

• root: “/”, “/ncep”• user1: “/ncep/UV.jan.nc”, “/ncep/UV.jan.nc/(U|V)”• user2: “/ncep/UV_500hPa_vect.png”

– permission for reading• everyone: “/”• groupA and groupB: “/ncep“, “/ncep/UV.jan.nc/(U|V)”• groupA: “/ncep/UV_500hPa_vect.png”

Page 34: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

• users and groups tables

• nodes table

id name owner

1 groupA user1

2 groupB user2

id name groups super_user

1 root 00000000 true

2 user1 00000011 false

3 user2 00000001 false

4 user3 00000000 false

id path owner other_mode rgroups wgroups

1 / 1 4 null null

2 /ncep 1 0 00000011 null

3 /ncep/UV.jan.nc 2 4 null null

4 /ncep/UV.jan.nc/U 2 4 null null

5 /ncep/UV.jan.nc/V 2 4 null null

6 /ncep/UV_500hPa_vect.png 3 0 00000001 null

The first bit is the flag for the group of id=1 (groupA),the second one is for that of id=2 (groupB),and so on.

The first bit is the flag for the group of id=1 (groupA),the second one is for that of id=2 (groupB),and so on.

They seem to be permitted to be accessed by anyone,but it is not so, because the permission for “/ncep” is inherited.They seem to be permitted to be accessed by anyone,but it is not so, because the permission for “/ncep” is inherited.

2: writable, 4: readable, 6:both2: writable, 4: readable, 6:both

Page 35: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

• Permission of a node depends on all its ancestors.– calculated in advance– saved at additional Boolean-type columns– In order to keep consistency, callbacks can be

added to events (e.g. after saving) with AR.

Page 36: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

• When permission is changed, the columns of its children are recalculated.– Using ActiveRecord, adding such callbacks to events

(e.g. after saving) is quite easy.

class Node < ActiveRecord::Base

after_save calculate_children_permissions # add a callback method

def calculate_permissions # calculation of permission other_readable = (other_mode & 4) & parent.other_readable groups_readable = rgroups & parent.groups_readable save! # save to database table end

def calculate_children_permissions # callback method children.each{|child| child.calculate_permissions } endend

Page 37: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

ER diagram of RDB tables

(only important tables and columns are shown)

Page 38: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

Registering script

• Directory tree structure on a storage is registered to the database table as it is.– The top directory to be registered can be

specified.

• Metadata contained in data files are registered to the database table.

• Any other metadata can be registered by writing in Yaml and SIGEN files.

Page 39: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails
Page 40: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

Analysis and Visualization• GPhys

– IO handling– data slice– mathematical calculation

• DCL (Dennou-Club Library)– plot

• (Cache)– drawn plots are cached to DB

Page 41: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

• Directory tree view

click

ajax request to get children directories

The ajax request will not be called again.Opening and closing the directory is doneby changing “display” attribute of CSS.

Page 42: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails
Page 43: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

RESTful

• Representational state transfer• Uniform interface

– All resource share a uniform interface like HTTP methods such as GET, POST, PUT, and DELETE.

• Resource Oriented Architecture– Every resources are uniquely addressable using URI.

• Statelessness– Each request is treated independently.

Page 44: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

improvable– still some separate codes

• web application, web service

– SOAP ignore HTTP methods.• Some cache systems could not work well.

– Programming with SOAP tend to be complicated.

“RESTful web service + client(s)”– one unified code

• Multiple output formats are still supported (HTML, XML).

– acts as definition of HTTP methods• cache system friendly

– simpler local programming

Page 45: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

RESTful webservice• URI syntax

– variable• http://host/…/ncep/UV.jan.nc/U.(html|xml)• http://host…/ncep/UV.jan.nc/children.(html|xml) # U and

V

– analysis• http://host/ .../{variables}/analysis/{function}.(html|xml)?{options}

– drawing• http://host/ .../{variables}/draw/{draw method}.(html|xml)?{options}

Page 46: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

clients• flex

– ActionScript– (AIR)

• (HTML + JavaScript)• (desktop ruby client)• another gfdnavi server

Page 47: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails
Page 48: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

UI with ajax

• asynchronous JavaScript and XML (originally)– not only JavaScript and XML, but also other pairs

• update a part of the existing page– better usability– reduce bandwidth usage

• Rails has many helper methods to write HTML and JavaScript to use ajax.

Page 49: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

click

get node list of the directory vie ajax call

Page 50: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

• Analysis page

check

get dimension’s information with ajax

click

send valuesin the formwith ajax

Page 51: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails
Page 52: Gfdnavi: its design and implementation with Ajax and Ruby-on-Rails

• Animation– the 1st loop

• ajax requests (one request for one image)• may take a little long time

– the later loops• cached image (cached as JavaScript object)