Skip to content

Commit

Permalink
removed randint, binary noise working, uses too much memory for > 200…
Browse files Browse the repository at this point in the history
…0 frames
  • Loading branch information
tbenst committed Nov 27, 2019
1 parent 6fad624 commit bd982d0
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 51 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ Or by using Image type, can just define in EPL preRenderFunc! See eyechart-sacca
replace koa-socket-session with something better supported (1.2.0 fails)
update to koa-socket-2
make sure I didn't break shuffle with new randint
websockets are crapping out on sending random frames, so need to do MT client-side & pass seed..?
- Chunk number of stimmuli returned


### video
- Always save video
Expand Down
6 changes: 3 additions & 3 deletions web/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ console.log("DATADIR: " + DATADIR)
const app = new Koa();
app.use(logger())

N_INIT_STIMULUS_QUEUE = 25

process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
// application specific logging, throwing an error, or other logic here
});



// VM2 ERROR HANDLING (per https://github.com/patriksimek/vm2/issues/87)
// can remove after pull request is merged
const StackTracey = require ('stacktracey');
Expand Down Expand Up @@ -159,7 +159,7 @@ function makeLabNotebook(labNotebook) {
function initStimulusQueue(prog) {
let stimulusQueue = []
assert(prog!==undefined, "No program found")
for (var i = 0; i < 5; i++) {
for (var i = 0; i < N_INIT_STIMULUS_QUEUE; i++) {
stimulusQueue.push(prog.next())
}
console.log(stimulusQueue)
Expand Down
7 changes: 1 addition & 6 deletions web/src/epl/random.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class DeterministicRandom {
let j
let a
for (var i = array.length - 1; i >= 1; i--) {
j = this.randint(0,i+1)
j = this.randi(0,i+1)
a = array[i]
array[i] = array[j]
array[j] = a
Expand All @@ -23,18 +23,13 @@ class DeterministicRandom {
return this.mt.random()
}

randint(start, end) {
return Math.round((end-start) * this.mt.random() + start)
}

// [start,end)
randi(start,end) {
const range = end - start
// sample must be divisible by range
const maxint = 2147483647
const max = maxint - (maxint%range)
let r = this.mt.int()
// TODO this seems super inefficient
while (r>max) {
r = this.mt.int()
}
Expand Down
68 changes: 41 additions & 27 deletions web/src/programs/acuity.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,27 +22,51 @@ function* measureIntegrity(stimuli,every=5*60) {

// special function for pre-rendering. This is passed as a string
// and run client-side
function preRenderFunc(nframes, pixelArrays) {
function preRenderFunc(binaryNoiseNframes, randomSeed) {
console.log("In preRender...")

console.assert(binaryNoiseNframes % 2 == 0)
// client-side
let r = new DeterministicRandom(randomSeed)

// render random binary frames that are balanced
// so average intensity per pixel over time is 0.5
// nframes must be even!
let nPixels = HEIGHT * WIDTH
// TODO delete / benchmark
// let r = new DeterministicRandom(10)
// let binaryNoiseNframes =14
let pixelArrays = []
let singlePixel = Uint8ClampedArray.from(Array(binaryNoiseNframes/2).fill(0).concat(Array(binaryNoiseNframes/2).fill(255)))
for (var p = 0; p < nPixels; p++) {
// benchmark: 50% of time is from shuffle
r.shuffle(singlePixel)
// ... allows for array copy
pixelArrays.push([...singlePixel])
if (p % 10000 == 0) {
console.log("pushed array for pixel: ", p)
}
}


// RGBA array https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas
let allFrames = new Uint8ClampedArray(nframes*nPixels*4)
let allFrames = new Uint8ClampedArray(binaryNoiseNframes*nPixels*4)
// values of single pixel over time
let singlePixel
// TODO why does making this nPixels/2 leave only ~1/4 of pixels with value??
for (var p = 0; p < nPixels; p++) {
singlePixel = pixelArrays[p]
for (var n = 0; n < nframes; n++) {
for (var n = 0; n < binaryNoiseNframes; n++) {
// For example, to read the blue component's value from the pixel at column 200, row 50 in the image, you would do the following:
// blueComponent = imageData.data[(50 * (imageData.width * 4)) + (200 * 4) + 2]
allFrames[p*4 + n*nPixels*4] = singlePixel[n] // red
allFrames[1+p*4 + n*nPixels*4] = singlePixel[n] // green
allFrames[2+p*4 + n*nPixels*4] = singlePixel[n] // blue
allFrames[3+p*4 + n*nPixels*4] = 255 // alpha
}
if (p % 10000 == 0) {
console.log("pushed array for pixel: ", p)
}

}

function renderFrame(flatPixelArray) {
Expand All @@ -56,9 +80,8 @@ function preRenderFunc(nframes, pixelArrays) {
}

let frames = []
for (var n = 0; n < nframes; n++) {
for (var n = 0; n < binaryNoiseNframes; n++) {
frames.push(renderFrame(allFrames.slice(n*nPixels*4,(n+1)*nPixels*4)))
console.log("Rendered frame: ", n)
}
console.log("frames[0]", frames[0])

Expand All @@ -67,20 +90,14 @@ function preRenderFunc(nframes, pixelArrays) {
}

// special object for pre-rendering
const binaryNoiseDuration = 1*60
const binaryNoiseDuration = 0.1*60
const frameRate = 60
const hz = 5
const binaryNoiseLifespan = 1 / hz
const binaryNoiseNframes = hz*binaryNoiseDuration
let nPixels = windowHeight * windowWidth
let pixelArrays = []
let singlePixel = Uint8ClampedArray.from(Array(binaryNoiseNframes/2).fill(0).concat(Array(binaryNoiseNframes/2).fill(255)))
for (var p = 0; p < nPixels; p++) {
r.shuffle(singlePixel)
// ... allows for array copy
pixelArrays.push([...singlePixel])
}
const preRenderArgs = [binaryNoiseNframes, pixelArrays]

const randomSeed = r.int()
const preRenderArgs = [binaryNoiseNframes, randomSeed]

// cell type assay
let celltypeStimuli = []
Expand All @@ -90,7 +107,11 @@ const celltypeMeta = {group: r.uuid(), label: "celltype"}
// let fixationPoint = {x: 0, y: 0}
let fixationPoint = {x: windowWidth/2, y: windowHeight/2}
for (var n = 0; n < binaryNoiseNframes; n++) {
celltypeStimuli.push(new Image(binaryNoiseLifespan, 'black', n, fixationPoint))
if (n==0) {
celltypeStimuli.push(new Image(binaryNoiseLifespan, 'black', n, fixationPoint, {"randomSeed": randomSeed}))
} else {
celltypeStimuli.push(new Image(binaryNoiseLifespan, 'black', n, fixationPoint))
}
}


Expand Down Expand Up @@ -131,16 +152,10 @@ celltypeStimuli.push(new Wait(3, celltypeMeta))
celltypeStimuli.push(new Solid(3, "blue", celltypeMeta))
celltypeStimuli.push(new Wait(3, celltypeMeta))

// binary dense noise OR white noise?
// perfectly balanced random sequence at 5 Hz yielding a total running time of 5 min
// TODO write binary dense noise stim
// implement as pre-generated images??

// let fixationPoint = {x: windowWidth/2, y: windowHeight/2}
// for (var n = 0; n < binaryNoiseNframes; n++) {
// celltypeStimuli.push(new Image(binaryNoiseLifespan, 'black', n, fixationPoint))
// }

// end cell type assay

let stimuli = []
Expand Down Expand Up @@ -178,10 +193,9 @@ for (let speed of speeds) {
}
}

// r.shuffle(stimuli)
// stimuli = measureIntegrity(flatten(stimuli))
// stimuli = celltypeStimuli.concat(stimuli)
stimuli = celltypeStimuli
r.shuffle(stimuli)
stimuli = measureIntegrity(flatten(stimuli))
stimuli = celltypeStimuli.concat(stimuli)

function* stimulusGenerator(renderResults) {
for (s of stimuli) {
Expand Down
9 changes: 1 addition & 8 deletions web/static/js/random.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class DeterministicRandom {
let j
let a
for (var i = array.length - 1; i >= 1; i--) {
j = this.randint(0,i+1)
j = this.randi(0,i+1)
a = array[i]
array[i] = array[j]
array[j] = a
Expand All @@ -23,18 +23,13 @@ class DeterministicRandom {
return this.mt.random()
}

randint(start, end) {
return Math.round((end-start) * this.mt.random() + start)
}

// [start,end)
randi(start,end) {
const range = end - start
// sample must be divisible by range
const maxint = 2147483647
const max = maxint - (maxint%range)
let r = this.mt.int()
// TODO this seems super inefficient
while (r>max) {
r = this.mt.int()
}
Expand All @@ -53,5 +48,3 @@ class DeterministicRandom {
return u
}
}

exports.DeterministicRandom = DeterministicRandom
6 changes: 0 additions & 6 deletions web/static/js/stimulus.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,3 @@ async function nextStimulus() {
}
return stimulus
}


/************************************************
RUN
************************************************/
// renderLoop()

0 comments on commit bd982d0

Please sign in to comment.