Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Meta modules #308

Merged
merged 14 commits into from
Aug 4, 2018
Merged

Meta modules #308

merged 14 commits into from
Aug 4, 2018

Conversation

tech4GT
Copy link
Member

@tech4GT tech4GT commented Jul 19, 2018

@jywarren meta modules🎉

tech4GT added 2 commits July 19, 2018 22:10
@ghost ghost assigned tech4GT Jul 19, 2018
@ghost ghost added the in-progress label Jul 19, 2018
@tech4GT
Copy link
Member Author

tech4GT commented Jul 19, 2018

@jywarren As of now meta-modules do not support any meta-data apart from a name, which means no description and their options are inherited from the sequence they are created, also I have added a button in the ui from which the current sequence can be saved as meta module, they are stored in the local-storage of the browser and inside a json fille in node

@jywarren
Copy link
Member

Wow, very cool! Can you walk me through how they work, by writing some docs? Imagine (haha) that i'm a developer first learning about the idea, and I can help by reading through the docs and code to see if it makes sense.

Very exciting!!!

@tech4GT
Copy link
Member Author

tech4GT commented Jul 20, 2018

@jywarren I'll add some comments and docs plus a test for this

tech4GT added 3 commits July 20, 2018 19:23
Signed-off-by: tech4GT <[email protected]>
Signed-off-by: tech4GT <[email protected]>
Signed-off-by: tech4GT <[email protected]>
README.md Outdated
@@ -461,6 +461,13 @@ sequencer.insertSteps({
```
return value: **`sequencer`** (To allow method chaining)

## Meta Modules

Image sequencer supports saving a sequence of modules and their associated settings(a stringified sequence) as a `meta-module`. These meta-modules are saved in the local storage inside the browser and inside a json file in node.js. Meta-modules can be saved in node context using the CLI option
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs a space here, small typo! and capitalize Image Sequencer? but looking great!

maybe and their associated settings in a simple string syntax, and then wrapping them up as a new module -- a "meta module" made of other modules. These meta-modules can be saved in ... or inside a json file.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done!!

README.md Outdated
```shell
--save-as-meta-module "name stringified-sequence"
```
Sequencer supports a function `sequencer.saveMetaModule(name,sequenceString)` which saves the given string as a meta module. The function `sequencer.loadModules()` reloads the modules and meta modules into `sequencer.modules` and `sequencer.metaModules`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image Sequencer can create/instantiate a new meta module with the function sequencer.saveMetaModule(name, sequenceString), which returns a new module containing the other modules.

Maybe also mention whether meta-modules can contain other meta modules?

And tell people to submit new meta-modules they create by opening an issue - they could be imported in or listed in the readme.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!!

Copy link
Member

@jywarren jywarren left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking great! Just a few tweaks here. Also, do you want to include one example meta-module, maybe in a subsequent PR, to link to from the docs? Or in an example, maybe? Could we have one core module be a meta module, to show an example?

@tech4GT
Copy link
Member Author

tech4GT commented Jul 20, 2018

@jywarren No meta-modules cannot contain other meta-modules and sure I'll add one example meta module, but should people contribute meta-modules?? they are just workflows so do we really want people to add them??

@jywarren
Copy link
Member

jywarren commented Jul 20, 2018 via email

@tech4GT
Copy link
Member Author

tech4GT commented Jul 20, 2018

@jywarren actually when we expand a meta-module we just find the constituent steps in core modules that is why this

@tech4GT
Copy link
Member Author

tech4GT commented Jul 20, 2018

@jywarren I'll Include this in the readme!!

// Save the given sequence string as a module
if (options.inBrowser) {
// Inside the browser we save the meta-modules using the Web Storage API
var metaModules = JSON.parse(window.localStorage.getItem('metaModules'));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, maybe we should think about the ability to createMetaModule() separately from where to store it. For example, shouldn't we be able to do:

var cropAndBlur = sequencer.createMetaModule('cropAndBlur', 'crop,blur');

sequencer. addSteps(cropAndBlur); // although i know we've used strings for this in the past... thoughts?

So a meta module would really be like a real module? Mind-bending, i know!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would we then essentially need to include a whole sequencer inside the meta module? so it can accept an input, and generate an output? Or is there a simpler way?

🤯

Copy link
Member Author

@tech4GT tech4GT Jul 20, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jywarren according to current structure we can do

sequencer.saveMetaModule('cropAndBlur','crop(),blur()')
sequencer.addSteps('cropAndBlur')

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jywarren we don't need that, we can just register it like a dynamic module from a string

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, but can't we just save it in memory for the time being, rather than in localStorage, and then think separately about reinstantiating them from other sources? I just want to think modularly here. saveMetaModule() could just generate the JSON, and then we could have separate methods for storing that in a persistent manner?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, true modules that are made up of other modules!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And thank you for thinking through this with me!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jywarren Actually the thing is that right now we are pulling the info in from the info of constituent modules so in order to have it support info for meta modules and have it load like normal modules needs fundamentally changing the way we do modules and bake in meta-modules there

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I think we are better off this way coz even if we try to make meta-modules like fully functional modules at some point we would have to expand them, what i mean is that at some point we would have to remove the meta-module from our steps array and we would have to push in the constituent modules before calling sequencer.run()

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jywarren This is a little hard to explain, Actually I started doing it but I realized this that we cannot make them like normal modules unless we find some way to execute the steps inside the meta-module like you said have an instance of sequencer inside of the module to execute the sequence and return the output

@tech4GT
Copy link
Member Author

tech4GT commented Jul 21, 2018

@jywarren sorry fo doing this here as well but I have also added the CLI for saving a module installed from npm. Here is the final workflow. register modules cli option installs the dependency from npm and saves it

sequencer --register-module "invert image-sequencer-invert"
sequencer -s invert -i ...

Signed-off-by: tech4GT <[email protected]>
@tech4GT
Copy link
Member Author

tech4GT commented Jul 24, 2018

@jywarren for meta modules I think we need to make a major design descision here since we can't do both, do we want the meta module to be a light weight sequence or a complete module with it's own info.json and stuff, I say we do the lightweight sequence, what do you say?

@jywarren
Copy link
Member

jywarren commented Jul 24, 2018 via email

@tech4GT
Copy link
Member Author

tech4GT commented Jul 24, 2018

@jywarren I'll start working on this now!!

@tech4GT
Copy link
Member Author

tech4GT commented Jul 24, 2018

A full module system will be very powerful @jywarren No doubt!! Let's do it then!!

@jywarren
Copy link
Member

jywarren commented Jul 24, 2018 via email

@tech4GT
Copy link
Member Author

tech4GT commented Jul 25, 2018

@jywarren So what I am trying to do now is that I am building an API that exposes the steps array to the step itself inside the draw method. So a meta-module in it's draw method would expand it's steps and push them into the sequencer steps array at runtime.

@tech4GT
Copy link
Member Author

tech4GT commented Jul 25, 2018

@jywarren can you please merge in #293 there is some code in there that I would like to use here. Thanks a lot!!

@tech4GT
Copy link
Member Author

tech4GT commented Jul 25, 2018

@jywarren One major issue that I am facing in this approach is how do we save the meta-module inside the browser context. I mean in node I can just generate a directory and a file called Modules.js and be done with it but when we are inside the browser I can't think of a way to make the meta-module persist unless I save the steps as JSON and then generate the meta-modules each time the browser reloads, do you think that is OK?

@tech4GT
Copy link
Member Author

tech4GT commented Jul 25, 2018

@jywarren We are done with this!!!!🎉🎉🎉🎉
The new implementation is exactly as you suggested and even more..

Meta Module:

Any module can be a meta-module now!! As I suggested earlier I have made an api that can expand the meta-module steps inside of the steps array. I have even made an example of this please see Ndvi-Colormap inside the modules. For the browser side I have created a function sequencer.createMetaModule(steps, info) through which meta-module can be created and added as a script so for instance somebody trying to do for ndvi and colormap this will say this

var ndvi-colormap = sequencer.createMetaModule('ndvi(),colormap()',{name: 'ndvi-colormap',description: 'blah blah'})
sequencer.loadNewModule(ndvi-colormap,'ndvi-colormap');

Saved Sequence

A user can save his/her sequence in both node(SavedSequencer.json) and browser context(localStorage), this will show up in their steps dropdown the next time so that they can quickly restore their workflow(in the future if you would like we can separate the steps and saved sequences)
So as an end user of sequencer I can add say five steps and then click the save-sequence button and then the next time in my steps dropdown i will find my saved sequence which I can click on and it will restore my progress!!

Signed-off-by: tech4GT <[email protected]>
@tech4GT
Copy link
Member Author

tech4GT commented Jul 25, 2018

This pr closes #190 and #200

Signed-off-by: tech4GT <[email protected]>
@ghost ghost added the in-progress label Jul 26, 2018
@jywarren
Copy link
Member

Sorry, i didn't get to this today! Had a big due date again. I'm going to look at it tomorrow, OK? THANKS VARUN!!! 👍

@tech4GT
Copy link
Member Author

tech4GT commented Jul 29, 2018

@jywarren also I'm kind of very busy for a few days now since my college interviews are going on... I hope that's fine!

@jywarren
Copy link
Member

Reading through this carefully NOW! 🎉

Copy link
Member

@jywarren jywarren left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a very good pr, very readable and excellently explained. I've left a few clarifying comments for documentation additions and a question about createMetaModule, but I'm really impressed here. Great work.

Last request - a test for metamodules? Could we test a metamodule against a sequence that should be identical, to demonstrate how it works? Probably in its own test file.

Then ready to merge!!!


## Meta Module

IMAGE SEQUENCER supports "meta modules" -- modules made of other modules. The syntax and structure of these meta modules is very similar to standard modules. Sequencer can also genarate meta modules dynamically with the function `createMetaModule` which can be called in the following ways
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great description!!!

CONTRIBUTING.md Outdated
```js
//index.js
module.exports = [
require('./Module.js)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops, comma needed here!

{
"name": "meta-moduleName",
"description": "",
"length": //Integer representing number of steps in the metaModule
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is "length" required? Or is it "nice to have"? Maybe add a note about this in the docs here?

@@ -104,8 +104,10 @@ Image Sequencer also provides a CLI for applying operations to local files. The
-b | --basic | Basic mode only outputs the final image
-o | --output [PATH] | Directory where output will be stored. (optional)
-c | --config {object} | Options for the step. (optional)
--save-sequence [string] | Name space separated with Stringified sequence to save
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...to save as a Meta module (see full docs) ?

@@ -104,8 +104,10 @@ Image Sequencer also provides a CLI for applying operations to local files. The
-b | --basic | Basic mode only outputs the final image
-o | --output [PATH] | Directory where output will be stored. (optional)
-c | --config {object} | Options for the step. (optional)
--save-sequence [string] | Name space separated with Stringified sequence to save
--install-module [string] | Module name space seaprated npm package name
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shall we show an example? this description is a little obscure.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jywarren including sample commands in the readme files

);
function refreshOptions() {
// Load information of all modules (Name, Inputs, Outputs)
var modulesInfo = sequencer.modulesInfo();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be the default, and be over-ridable? Or not worth it?

sequencer.saveSequence(params[0], params[1]);
} else if (program.installModule) {
var params = program.installModule.split(' ');
var spinner = Spinner("Now Installing...").start();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh wow. Is this tested?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jywarren yes!!

@@ -324,12 +345,62 @@ ImageSequencer = function ImageSequencer(options) {
return this;
}

function saveNewModule(name, path) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoa, how does this work?

}

function saveSequence(name, sequenceString) {
const sequence = stringToJSON(sequenceString);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are so nice with this general purpose function! Nice and short and readable.

* Sample Meta Module for demonstration purpose only
*/
module.exports = function NdviColormapfunction() {
this.expandSteps([{ 'name': 'ndvi', 'options': {} }, { 'name': 'colormap', options: {} }]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I'm wondering one last thing, could we create a metal module from a json object with createMetaModule right here, alternatively? Any pros or cons to that rather than using expandSteps? Cool!

Signed-off-by: tech4GT <[email protected]>
@tech4GT
Copy link
Member Author

tech4GT commented Aug 2, 2018

@jywarren I'll summarize everything here
install-module option firstly installs the given module from npm and then calls the save-module function to save it into sequencer by modifying the modules.js file itself. this means that the CLI user has to just enter one command on the terminal and the dependency is downloaded saved and registered into sequencer and is ready to use.
sequencer.createMetaModule can create modules on the fly with the json object and that is the intended way of making meta-modules for the ui. Also what i have demonstrated is that we can create a meta module like a regular module inside a file but all we have to do inside the module if we wish to write it ourselves is call the sequencer.expandsteps at the end of it so that the constituent steps can be pushed on the the steps array. We can say that the function exapndsteps just expands the given steps and pushes them onto the the steps array.

@tech4GT
Copy link
Member Author

tech4GT commented Aug 2, 2018

And Done!! @jywarren I think that does it all!! Tested and documented🎉

Signed-off-by: tech4GT <[email protected]>
@jywarren
Copy link
Member

jywarren commented Aug 4, 2018

Great, i think we are ready to merge this -- let me test it today and I'll do it.

I was waiting because i wasn't sure of one thing -- when expandSteps is run, the meta module disappears and is replaced by the sub-modules in the main sequencer? Am I right in understanding this?

If so, I want to explore a future version where they are permanently kept inside the meta module, so no external modules ever know how the meta module took an input and produced an output. I think this kind of "wrapper" meta module, that doesn't reveal its internals, is ideal for a number of reasons. Thoughts?

But it can be in a future version! If my understanding above is correct, we are all good here! Merge?

CONTRIBUTING.md Outdated
```
The length is absolutely required for a meta-module, since sequencer is optimized to re-run minimum number of steps when a step is added in the UI which is 1 in the case of normal modules, if the added step is a meta-module the length of the sequence governs the number of steps to re-run.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So with meta modules that don't get expanded into multiple main sequencer steps, but keep them internal only, this requirement might go away?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jywarren Then that meta-module would just be a normal module, so yeah no need then :D

@jywarren
Copy link
Member

jywarren commented Aug 4, 2018

What do you say, Varun, shall I go ahead and merge now? Thanks!

@tech4GT
Copy link
Member Author

tech4GT commented Aug 4, 2018

@jywarren Yeah we can do that in the future update!! Let's merge this!! Awesome!!🎉

@jywarren jywarren merged commit 5ab018f into publiclab:master Aug 4, 2018
@ghost ghost removed the in-progress label Aug 4, 2018
@jywarren
Copy link
Member

jywarren commented Aug 4, 2018

Hooray!!!!!!!👍🏼👍🏼👍🏼

@tech4GT
Copy link
Member Author

tech4GT commented Aug 4, 2018

@jywarren Let's wait on pushing it out to production though, let's add the colorbar module first

@jywarren
Copy link
Member

jywarren commented Aug 4, 2018 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants