summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/client/modules/pix2pix/pix2pix.actions.js6
-rw-r--r--app/client/modules/pix2wav/index.js1
-rw-r--r--app/client/modules/pix2wav/pix2wav.actions.js27
-rw-r--r--app/client/modules/pix2wav/pix2wav.tasks.js11
-rw-r--r--app/client/modules/pix2wav/views/pix2wav.live.js317
5 files changed, 356 insertions, 6 deletions
diff --git a/app/client/modules/pix2pix/pix2pix.actions.js b/app/client/modules/pix2pix/pix2pix.actions.js
index 2ca3654..e15ea86 100644
--- a/app/client/modules/pix2pix/pix2pix.actions.js
+++ b/app/client/modules/pix2pix/pix2pix.actions.js
@@ -23,7 +23,6 @@ export const load_directories = (id) => (dispatch) => {
console.log('pix2pix load progress', i, n)
dispatch({ type: types.app.load_progress, progress: { i, n }})
}).then(res => {
- // console.log(res)
const [datasetApiReport, sequences, datasets, checkpoints] = res //, datasets, results, output, datasetUsage, lossReport] = res
const {
folderLookup,
@@ -35,7 +34,6 @@ export const load_directories = (id) => (dispatch) => {
} = datasetApiReport
// console.log(datasetUsage)
- // const flatDatasets = datasets.filter(s => !s.dir)
const sequenceDirectories = sequences.filter(s => s.dir)
sequenceDirectories.forEach(dir => {
const dataset = datasetLoader.getDataset(module, datasetLookup, dir.name)
@@ -53,7 +51,7 @@ export const load_directories = (id) => (dispatch) => {
dataset.hasCheckpoints = true
})
- console.log(res)
+ // console.log(res)
// flatDatasets.forEach(file => {
// file.uuid = uuidv1()
@@ -118,8 +116,6 @@ export const load_directories = (id) => (dispatch) => {
sequences: sequenceDirectories,
datasets,
checkpoints: checkpointDirectories,
- // checkpoints,
- // output,
},
})
if (id) {
diff --git a/app/client/modules/pix2wav/index.js b/app/client/modules/pix2wav/index.js
index 36c4039..b73a5df 100644
--- a/app/client/modules/pix2wav/index.js
+++ b/app/client/modules/pix2wav/index.js
@@ -13,6 +13,7 @@ function router () {
<Route exact path='/pix2wav/new/' component={Pix2WavNew} />
<Route exact path='/pix2wav/datasets/' component={Pix2WavShow} />
<Route exact path='/pix2wav/datasets/:id/' component={Pix2WavShow} />
+ <Route exact path='/pix2wav/live/' component={Pix2WavLive} />
</section>
)
}
diff --git a/app/client/modules/pix2wav/pix2wav.actions.js b/app/client/modules/pix2wav/pix2wav.actions.js
index 08f1a97..9d819a3 100644
--- a/app/client/modules/pix2wav/pix2wav.actions.js
+++ b/app/client/modules/pix2wav/pix2wav.actions.js
@@ -15,6 +15,9 @@ export const load_directories = (id) => (dispatch) => {
const module = pix2wavModule.name
util.allProgress([
datasetLoader.load(module),
+ actions.socket.list_directory({ module, dir: 'sequences/pix2wav/' }),
+ actions.socket.list_directory({ module, dir: 'datasets/pix2wav/' }),
+ actions.socket.list_directory({ module, dir: 'checkpoints/pix2wav/' }),
// actions.socket.list_directory({ module, dir: 'datasets' }),
// actions.socket.list_directory({ module, dir: 'results' }),
// actions.socket.list_directory({ module, dir: 'output' }),
@@ -22,7 +25,7 @@ export const load_directories = (id) => (dispatch) => {
], (percent, i, n) => {
dispatch({ type: types.app.load_progress, progress: { i, n }})
}).then(res => {
- const [datasetApiReport] = res //, datasets, results, output, datasetUsage, lossReport] = res
+ const [datasetApiReport, sequences, datasets, checkpoints] = res
const {
folderLookup,
fileLookup,
@@ -31,6 +34,24 @@ export const load_directories = (id) => (dispatch) => {
files,
unsortedFolder,
} = datasetApiReport
+
+ const sequenceDirectories = sequences.filter(s => s.dir)
+ sequenceDirectories.forEach(dir => {
+ const dataset = datasetLoader.getDataset(module, datasetLookup, dir.name)
+ dataset.isBuilt = true
+ })
+
+ datasets.filter(s => s.dir).forEach(dir => {
+ const dataset = datasetLoader.getDataset(module, datasetLookup, dir.name)
+ dataset.hasDataset = true
+ })
+
+ const checkpointDirectories = checkpoints.filter(s => s.dir)
+ checkpointDirectories.forEach(dir => {
+ const dataset = datasetLoader.getDataset(module, datasetLookup, dir.name)
+ dataset.hasCheckpoints = true
+ })
+
dispatch({
type: types.dataset.load,
data: {
@@ -39,8 +60,12 @@ export const load_directories = (id) => (dispatch) => {
fileLookup,
datasetLookup,
folders, files,
+ sequences: sequenceDirectories,
+ datasets,
+ checkpoints: checkpointDirectories,
},
})
+
if (id) {
console.log('folder id', id)
dispatch({
diff --git a/app/client/modules/pix2wav/pix2wav.tasks.js b/app/client/modules/pix2wav/pix2wav.tasks.js
index 646e28c..fa40bf9 100644
--- a/app/client/modules/pix2wav/pix2wav.tasks.js
+++ b/app/client/modules/pix2wav/pix2wav.tasks.js
@@ -5,3 +5,14 @@ import types from '../../types'
import actions from '../../actions'
+export const live_task = (sequence, checkpoint) => dispatch => {
+ const task = {
+ module: 'pix2wav',
+ activity: 'live',
+ dataset: sequence,
+ checkpoint,
+ }
+ console.log(task)
+ console.log('add live task')
+ return actions.queue.add_task(task)
+}
diff --git a/app/client/modules/pix2wav/views/pix2wav.live.js b/app/client/modules/pix2wav/views/pix2wav.live.js
new file mode 100644
index 0000000..2902bff
--- /dev/null
+++ b/app/client/modules/pix2wav/views/pix2wav.live.js
@@ -0,0 +1,317 @@
+import { h, Component } from 'preact'
+import { bindActionCreators } from 'redux'
+import { connect } from 'react-redux'
+
+import {
+ ParamGroup, Param, Player,
+ Slider, Select, Button, Loading
+} from '../../../common/'
+
+import { startRecording, stopRecording, saveFrame } from '../../../live/player'
+
+import * as liveActions from '../../../live/live.actions'
+import * as queueActions from '../../../queue/queue.actions'
+import * as pix2wavTasks from '../pix2wav.tasks'
+import * as pix2wavActions from '../pix2wav.actions'
+
+class Pix2WavLive extends Component {
+ constructor(props){
+ super()
+ props.actions.pix2wav.load_directories()
+ props.actions.live.get_params()
+ this.changeCheckpoint = this.changeCheckpoint.bind(this)
+ this.changeEpoch = this.changeEpoch.bind(this)
+ this.changeSequence = this.changeSequence.bind(this)
+ this.seek = this.seek.bind(this)
+ this.togglePlaying = this.togglePlaying.bind(this)
+ this.toggleRecording = this.toggleRecording.bind(this)
+ }
+ componentWillUpdate(nextProps) {
+ if (nextProps.opt.checkpoint_name && nextProps.opt.checkpoint_name !== this.props.opt.checkpoint_name) {
+ this.props.actions.live.list_epochs('pix2wav', nextProps.opt.checkpoint_name)
+ }
+ }
+ changeCheckpoint(field, checkpoint_name){
+ this.props.actions.live.load_epoch(checkpoint_name, 'latest')
+ }
+ changeEpoch(field, epoch_name){
+ this.props.actions.live.load_epoch(this.props.opt.checkpoint_name, epoch_name)
+ }
+ changeSequence(field, sequence){
+ console.log('got sequence', sequence)
+ this.props.actions.live.load_sequence(sequence)
+ }
+ seek(percentage){
+ const frame = Math.floor(percentage * (parseInt(this.props.frame.sequence_len) || 1) + 1)
+ this.props.actions.live.seek(frame)
+ }
+ start(){
+ // console.log(this.props)
+ const sequence = this.props.pix2wav.data.sequences[0].name
+ const checkpoint = this.props.pix2wav.data.checkpoints[0].name
+ console.log('starting up!', sequence, checkpoint)
+ this.props.actions.tasks.live_task(sequence, checkpoint)
+ }
+ interrupt(){
+ this.props.actions.queue.stop_task('gpu')
+ }
+ togglePlaying(){
+ if (this.props.opt.processing) {
+ this.props.actions.live.pause()
+ } else {
+ this.props.actions.live.play()
+ }
+ }
+ toggleRecording(){
+ if (this.props.opt.recording){
+ stopRecording()
+ this.props.actions.live.pause()
+ } else {
+ startRecording()
+ }
+ }
+ render(){
+ // console.log(this.props)
+ if (this.props.pix2wav.loading) {
+ return <Loading />
+ }
+ return (
+ <div className='app centered'>
+ <Player width={424} height={256} />
+ <div className='params row'>
+ <div className='column'>
+ <ParamGroup
+ title='Playback'
+ noToggle
+ >
+ <Select
+ name='send_image'
+ title='view mode'
+ options={['a','b','sequence','recursive']}
+ onChange={this.props.actions.live.set_param}
+ />
+ <Select
+ name='sequence_name'
+ title='sequence'
+ options={this.props.pix2wav.data.sequences.map(file => file.name)}
+ onChange={this.changeSequence}
+ />
+ <Select
+ name='checkpoint_name'
+ title='checkpoint'
+ options={this.props.pix2wav.data.checkpoints.map(file => file.name)}
+ onChange={this.changeCheckpoint}
+ />
+ <Select
+ name='epoch'
+ title='epoch'
+ options={this.props.epochs}
+ onChange={this.changeEpoch}
+ />
+ <Slider live
+ name='position'
+ min={0.0} max={1.0} type='float'
+ value={(this.props.frame.sequence_i || 0) / (this.props.frame.sequence_len || 1)}
+ onChange={this.seek}
+ />
+ {this.renderRestartButton()}
+ <Button
+ title={
+ this.props.opt.savingVideo
+ ? 'Saving video...'
+ : this.props.opt.recording
+ ? 'Recording (' + timeInSeconds(this.props.opt.recordFrames) +')'
+ : 'Record video'
+ }
+ onClick={this.toggleRecording}
+ >
+ {this.props.opt.savingVideo ? 'Saving' : this.props.opt.recording ? 'Recording' : 'Record'}
+ </Button>
+ <Button
+ title={'Save frame'}
+ onClick={saveFrame}
+ >
+ Save
+ </Button>
+
+ <p class='last_message'>{this.props.last_message}</p>
+ </ParamGroup>
+ </div>
+ <div className='column'>
+ <ParamGroup
+ title='Transition'
+ name='transition'
+ >
+ <Slider live
+ name='transition_period'
+ min={10} max={5000} type='int'
+ />
+ <Slider live
+ name='transition_min'
+ min={0.001} max={0.2} type='float'
+ />
+ <Slider live
+ name='transition_max'
+ min={0.1} max={1.0} type='float'
+ />
+ </ParamGroup>
+
+ <ParamGroup
+ title='Recursion'
+ name='recursive'
+ >
+ <Slider live
+ name='recursive_frac'
+ min={0.0} max={0.5} type='float'
+ />
+ <Slider live
+ name='recurse_roll'
+ min={-64} max={64} type='int'
+ />
+ <Slider live
+ name='recurse_roll_axis'
+ min={0} max={1} type='int'
+ />
+ </ParamGroup>
+
+ <ParamGroup
+ title='Sequence'
+ name='sequence'
+ >
+ <Slider live
+ name='sequence_frac'
+ min={0.0} max={0.5} type='float'
+ />
+ <Slider live
+ name='process_frac'
+ min={0} max={1} type='float'
+ />
+ </ParamGroup>
+ </div>
+ <div className='column'>
+ <ParamGroup
+ title='Clahe'
+ name='clahe'
+ >
+ <Slider live
+ name='clip_limit'
+ min={1.0} max={4.0} type='float'
+ />
+ </ParamGroup>
+
+ <ParamGroup
+ title='Posterize'
+ name='posterize'
+ >
+ <Slider live
+ name='spatial_window'
+ min={2} max={128} type='int'
+ />
+ <Slider live
+ name='color_window'
+ min={2} max={128} type='int'
+ />
+ </ParamGroup>
+
+ <ParamGroup
+ title='Blur'
+ name='blur'
+ >
+ <Slider live
+ name='blur_radius'
+ min={3} max={7} type='odd'
+ />
+ <Slider live
+ name='blur_sigma'
+ min={0} max={2} type='float'
+ />
+ </ParamGroup>
+
+ <ParamGroup
+ title='Canny Edge Detection'
+ name='canny'
+ >
+ <Slider live
+ name='canny_lo'
+ min={10} max={200} type='int'
+ />
+ <Slider live
+ name='canny_hi'
+ min={10} max={200} type='int'
+ />
+ </ParamGroup>
+
+ </div>
+ </div>
+ </div>
+ )
+ }
+ renderRestartButton(){
+ if (this.props.runner.gpu.status === 'IDLE') {
+ return (
+ <Button
+ title={'GPU Idle'}
+ onClick={() => this.start()}
+ >Start</Button>
+ )
+ }
+ if (this.props.runner.gpu.task.module !== 'pix2wav') {
+ return (
+ <Button
+ title={'GPU Busy'}
+ onClick={() => this.interrupt()}
+ >Interrupt</Button>
+ )
+ }
+ if (! this.props.opt.processing) {
+ return (
+ <div>
+ <Button
+ title={'Not processing'}
+ onClick={this.togglePlaying}
+ >Restart</Button>
+ <Button
+ title={'GPU Busy'}
+ onClick={() => this.interrupt()}
+ >Interrupt</Button>
+ </div>
+ )
+ }
+ return (
+ <div>
+ <Button
+ title={'Processing'}
+ onClick={this.togglePlaying}
+ >Pause</Button>
+ <Button
+ title={'GPU Busy'}
+ onClick={() => this.interrupt()}
+ >Interrupt</Button>
+ </div>
+ )
+ }
+}
+function timeInSeconds(n){
+ return (n / 10).toFixed(1) + ' s.'
+}
+const mapStateToProps = state => ({
+ last_message: state.live.last_message,
+ opt: state.live.opt,
+ frame: state.live.frame,
+ checkpoints: state.live.checkpoints,
+ epochs: state.live.epochs,
+ sequences: state.live.sequences,
+ runner: state.system.runner,
+ pix2wav: state.module.pix2wav,
+})
+
+const mapDispatchToProps = (dispatch, ownProps) => ({
+ actions: {
+ live: bindActionCreators(liveActions, dispatch),
+ queue: bindActionCreators(queueActions, dispatch),
+ pix2wav: bindActionCreators(pix2wavActions, dispatch),
+ tasks: bindActionCreators(pix2wavTasks, dispatch),s
+ }
+})
+
+export default connect(mapStateToProps, mapDispatchToProps)(Pix2WavLive)