Permalink
Please sign in to comment.
Browse files
Afra
* proof of concept * IE10 and above only. * Annotation editor. Launch the server and direct the browser to `/#/curate`. Login, if need be, and you will see the first curation task. Hit `Done` to save the curated gene model on the server and move to the next task. Annotation editing functionality builds on the excellent work done by JBrowse and WebApollo. JBrowse / WebApollo integration ------------------------------- JB and WA code, with several modifications, lives as a part of the source tree in app/src/JBrowse and JBrowse/WebApollo. JB contains upstream’s src/JBrowse, img, and all CSS (including that of WA -- just one line) compiled into one styles.css. JB/WA contains upstream’s WA/js. I hacked JB’s plugin system so that loading CSS for plugins is none of it’s concern, additionally removing the dependency on lazyload. JB/main.js loads styles.css using require-css and WA using the reduced plugin architecture. This combines JB & WA into one unit. JB/main.js instantiates JB and returns a facade object. Rest of Afra inter-operates with JB through the facade. At the moment we have a single API call, `load`, to load a task into JB. We will need another API call to access contents of the annotations track. JB’s dependencies are managed through Bower. I have locked to the latest point-release of the dependencies that follow semantic versioning. While we track rolling updates from Github for the rest -- either Bower doesn’t support locking to a SHA or it just didn’t work on my Mac. It’s worth noting that these dependencies are extremely focussed and move slow: hopefully things won’t break for a while. In the near future, we should be able to remove a few more dependencies and / or lock to a working SHA using Bower. Modified default track styles for JB so it looks quite presentable. Perl sub-system of JB & WA is a part of the source tree as well. setup.sh lives as a part of `rake setup` and installs dependencies to $HOME/.extlib. Additionally, I dropped support for the deprecated legacy wiggle format and legacy bam-to-json.pl. Included for testing, MAKER2 generated gene prediction in GFF3 format for two scaffolds of fire ant genome. And, * drop more than one feature * make exons resizable * trying add_exon * jbrowse refresh hack * Done button fully functional: put submission, get a new task and load it. Squashed commits ---------------- JB: change zoom level on scroll wheel. overlay zoom buttons over genome viewer in a horizontal orientation merge wa and jb 1. Removed TrackTransformer stuff - DraggableHTMLFeatures now the default for FeatureTrack. 2. Merge permission.js and annottrack.js - will eventually remove permission stuff. * remove jb nav * remove tracklist * remove not needed dep on dijit/ * increase initial height of edit track * do not scroll to bottom on page load #6 * rework track spacing and padding * track padding * track-label * remove feature right-click menu * trimming annottrack.js - removed right click menu and stuff * edit track annot css DnD: * If the annotation wasn't dropped on edit track, bring it back to * clear selection after annot dropped * use black color for edge matching * 4px black border for selection * uri decode gff stream * fix anno saving * and reset feature start and end, if need be, on resize exon * try add exon again * Mention we support Google Chrome only at the moment on #signin. * fb popup * package.json Signed-off-by: Anurag Priyam <anurag08priyam@gmail.com>
- Loading branch information...
| @@ -0,0 +1,2 @@ | ||
| +* | ||
| +!.gitignore |
| @@ -0,0 +1,7 @@ | ||
| +Gemfile.lock | ||
| +node_modules | ||
| +www/lib | ||
| +MYMETA.yml | ||
| +MYMETA.json | ||
| +Makefile | ||
| +data |
| @@ -0,0 +1 @@ | ||
| +2.1.0 |
223
ArrayRepr.pm
| @@ -0,0 +1,223 @@ | ||
| +package ArrayRepr; | ||
| + | ||
| +use strict; | ||
| +use warnings; | ||
| +use Carp; | ||
| + | ||
| +=head1 DESCRIPTION | ||
| + | ||
| + The ArrayRepr class is for operating on indexed representations of objects. | ||
| + | ||
| + For example, if we have a lot of objects with similar attributes, e.g.: | ||
| + | ||
| + [ | ||
| + {start: 1, end: 2, strand: -1}, | ||
| + {start: 5, end: 6, strand: 1}, | ||
| + ... | ||
| + ] | ||
| + | ||
| + we can represent them more compactly (e.g., in JSON) something like this: | ||
| + | ||
| + class = ["start", "end", "strand"] | ||
| + | ||
| + [ | ||
| + [1, 2, -1], | ||
| + [5, 6, 1], | ||
| + ... | ||
| + ] | ||
| + | ||
| + If we want to represent a few different kinds of objects in our big list, | ||
| + we can have multiple "class" arrays, and tag each object to identify | ||
| + which "class" array describes it. | ||
| + | ||
| + For example, if we have a lot of instances of a few types of objects, | ||
| + like this: | ||
| + | ||
| + [ | ||
| + {start: 1, end: 2, strand: 1, id: 1}, | ||
| + {start: 5, end: 6, strand: 1, id: 2}, | ||
| + ... | ||
| + {start: 10, end: 20, chunk: 1}, | ||
| + {start: 30, end: 40, chunk: 2}, | ||
| + ... | ||
| + ] | ||
| + | ||
| + We could use the first array position to indicate the "class" for the | ||
| + object, like this: | ||
| + | ||
| + classes = [["start", "end", "strand", "id"], ["start", "end", "chunk"]] | ||
| + | ||
| + [ | ||
| + [0, 1, 2, 1, 1], | ||
| + [0, 5, 6, 1, 2], | ||
| + ... | ||
| + [1, 10, 20, 1], | ||
| + [1, 30, 40, 1] | ||
| + ] | ||
| + | ||
| + Also, if we occasionally want to add an ad-hoc attribute, we could just | ||
| + stick an optional dictionary onto the end: | ||
| + | ||
| + classes = [["start", "end", "strand", "id"], ["start", "end", "chunk"]] | ||
| + | ||
| + [ | ||
| + [0, 1, 2, 1, 1], | ||
| + [0, 5, 6, 1, 2, {foo: 1}] | ||
| + ] | ||
| + | ||
| + Given that individual objects are being represented by arrays, generic | ||
| + code needs some way to differentiate arrays that are meant to be objects | ||
| + from arrays that are actually meant to be arrays. | ||
| + So for each class, we include a dict with <attribute name>: true mappings | ||
| + for each attribute that is meant to be an array. | ||
| + | ||
| + Also, in cases where some attribute values are the same for all objects | ||
| + in a particular set, it may be convenient to define a prototype ("proto") | ||
| + with default values for all objects in the set | ||
| + | ||
| + In the end, we get something like this: | ||
| + | ||
| + classes = [ | ||
| + { "attributes" : [ "Start", "End", "Subfeatures" ], | ||
| + "proto" : { "Chrom" : "chr1" }, | ||
| + "isArrayAttr" : { "Subfeatures" : true } | ||
| + } | ||
| + ] | ||
| + | ||
| + That's what this class facilitates. | ||
| + | ||
| +=cut | ||
| + | ||
| +sub new { | ||
| + my ($class, $classes) = @_; | ||
| + | ||
| + # fields is an array of (map from attribute name to attribute index) | ||
| + my @fields; | ||
| + for my $attributes ( map $_->{attributes}, @$classes ) { | ||
| + my $field_index = 1; | ||
| + push @fields, { map { $_ => $field_index++ } @$attributes }; | ||
| + } | ||
| + | ||
| + my $self = { | ||
| + 'classes' => $classes, | ||
| + 'fields' => \@fields | ||
| + }; | ||
| + | ||
| + bless $self, $class; | ||
| + return $self; | ||
| +} | ||
| + | ||
| +sub attrIndices { | ||
| + my ($self, $attr) = @_; | ||
| + return [ map { $_->{$attr} } @{$self->{'fields'}} ]; | ||
| +} | ||
| + | ||
| +sub get { | ||
| + my ($self, $obj, $attr) = @_; | ||
| + my $fields = $self->{'fields'}->[$obj->[0]]; | ||
| + if (defined($fields) && defined($fields->{$attr})) { | ||
| + return $obj->[$fields->{$attr}]; | ||
| + } else { | ||
| + my $cls = $self->{'classes'}->[$obj->[0]]; | ||
| + return unless defined($cls); | ||
| + my $adhocIndex = $#{$cls->{'attributes'}} + 2; | ||
| + if (($adhocIndex > $#{$obj}) | ||
| + or (not defined($obj->[$adhocIndex]->{$attr})) ) { | ||
| + if (defined($cls->{'proto'}) | ||
| + and (defined($cls->{'proto'}->{$attr})) ) { | ||
| + return $cls->{'proto'}->{$attr}; | ||
| + } | ||
| + return undef; | ||
| + } | ||
| + return $obj->[$adhocIndex]->{$attr}; | ||
| + } | ||
| +} | ||
| + | ||
| +sub fastGet { | ||
| + # this method can be used if the attribute is guaranteed to be in | ||
| + # the attributes array for the object's class | ||
| + my ($self, $obj, $attr) = @_; | ||
| + return $obj->[$self->{'fields'}->[$obj->[0]]->{$attr}]; | ||
| +} | ||
| + | ||
| +sub set { | ||
| + my ($self, $obj, $attr, $val) = @_; | ||
| + my $fields = $self->{'fields'}->[$obj->[0]]; | ||
| + if (defined($fields) && defined($fields->{$attr})) { | ||
| + $obj->[$fields->{$attr}] = $val; | ||
| + } else { | ||
| + my $cls = $self->{'classes'}->[$obj->[0]]; | ||
| + return unless defined($cls); | ||
| + my $adhocIndex = $#{$cls->{'attributes'}} + 2; | ||
| + if ($adhocIndex > $#{$obj}) { | ||
| + $obj->[$adhocIndex] = {} | ||
| + } | ||
| + $obj->[$adhocIndex]->{$attr} = $val; | ||
| + } | ||
| +} | ||
| + | ||
| +sub fastSet { | ||
| + # this method can be used if the attribute is guaranteed to be in | ||
| + # the attributes array for the object's class | ||
| + my ($self, $obj, $attr, $val) = @_; | ||
| + $obj->[$self->{'fields'}->[$obj->[0]]->{$attr}] = $val; | ||
| +} | ||
| + | ||
| +sub makeSetter { | ||
| + my ($self, $attr) = @_; | ||
| + return sub { | ||
| + my ($obj, $val) = @_; | ||
| + $self->set($obj, $attr, $val); | ||
| + }; | ||
| +} | ||
| + | ||
| +sub makeGetter { | ||
| + my ($self, $attr) = @_; | ||
| + return sub { | ||
| + my ($obj) = @_; | ||
| + return $self->get($obj, $attr); | ||
| + }; | ||
| +} | ||
| + | ||
| +sub makeFastSetter { | ||
| + # this method can be used if the attribute is guaranteed to be in | ||
| + # the attributes array for the object's class | ||
| + my ($self, $attr) = @_; | ||
| + my $indices = $self->attrIndices($attr); | ||
| + return sub { | ||
| + my ($obj, $val) = @_; | ||
| + if (defined($indices->[$obj->[0]])) { | ||
| + $obj->[$indices->[$obj->[0]]] = $val; | ||
| + } else { | ||
| + # report error? | ||
| + } | ||
| + }; | ||
| +} | ||
| + | ||
| +sub makeFastGetter { | ||
| + # this method can be used if the attribute is guaranteed to be in | ||
| + # the attributes array for the object's class | ||
| + my ($self, $attr) = (@_); | ||
| + my $indices = $self->attrIndices($attr); | ||
| + croak "no attribute '$attr' found in representation" unless grep defined, @$indices; | ||
| + return sub { | ||
| + my ($obj) = @_; | ||
| + if ( defined $obj && defined $obj->[0] && defined $indices->[ $obj->[0] ] ) { | ||
| + return $obj->[$indices->[$obj->[0]]]; | ||
| + } else { | ||
| + # report error? | ||
| + return undef; | ||
| + } | ||
| + }; | ||
| +} | ||
| + | ||
| +sub construct { | ||
| + my ($self, $dict, $cls) = @_; | ||
| + my $result = []; | ||
| + foreach my $key (keys %$dict) { | ||
| + $self->set($result, $key, $dict->{$key}); | ||
| + } | ||
| + return $result; | ||
| +} | ||
| + | ||
| +1; |
Oops, something went wrong.
0 comments on commit
b112427