Skip to content

Commit

Permalink
Merge pull request nglviewer#942 from fredludlow/refreshed-signal
Browse files Browse the repository at this point in the history
Proposal - changing structure.refreshed signal and logic
  • Loading branch information
ppillot committed May 3, 2023
2 parents bbfc58b + 047f756 commit 6be10a3
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 23 deletions.
8 changes: 4 additions & 4 deletions src/component/structure-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ class StructureComponent extends Component {
//

this.setDefaultAssembly(this.parameters.defaultAssembly)

this.structure.signals.refreshed.add(() => {
this.updateRepresentations({ position: true })
})
}

/**
Expand Down Expand Up @@ -289,10 +293,6 @@ class StructureComponent extends Component {
addTrajectory (trajPath = '', params: { [k: string]: any } = {}) {
const traj = makeTrajectory(trajPath, this.structureView, params as TrajectoryParameters)

traj.signals.frameChanged.add(() => {
this.updateRepresentations({ 'position': true })
})

const trajComp = new TrajectoryElement(this.stage, traj, params)
this.trajList.push(trajComp)
this.signals.trajectoryAdded.dispatch(trajComp)
Expand Down
22 changes: 18 additions & 4 deletions src/structure/structure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1059,23 +1059,37 @@ class Structure implements Structure{
return chainnames.size
}

//

updatePosition (position: Float32Array|number[]) {
/**
* Update atomic positions
* @param position - Array to copy positions from
* @param refresh - Whether or not to issue a full refresh (automatically
* triggers re-calculation of bounding boxes, spatial hash,
* representations etc etc). This provides compatibility with
* the old behaviour
*/
updatePosition (position: Float32Array|number[], refresh: boolean = true) {
let i = 0

this.eachAtom(function (ap: AtomProxy) {
ap.positionFromArray(position, i)
i += 3
}, undefined)

this._hasCoords = undefined // to trigger recalculation
this._hasCoords = undefined // to trigger recalculation (of the _hasCoords value)

if (refresh) {
this.refreshPosition() // Recalculate bounds - structure-component listener will
// trigger representation rebuild
}

}

refreshPosition () {
this.getBoundingBox(undefined, this.boundingBox)
this.boundingBox.getCenter(this.center)
this.spatialHash = new SpatialHash(this.atomStore, this.boundingBox)

this.signals.refreshed.dispatch(this)
}

/**
Expand Down
72 changes: 57 additions & 15 deletions test/structure/tests-structure.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,64 @@ import PdbParser from '../../src/parser/pdb-parser'


import { join } from 'path'
import * as fs from 'fs'

describe('structure/structure', function () {
describe('iteration', function () {
it('polymer no chains', function () {
var file = join(__dirname, '/../data/BaceCgProteinAtomistic.pdb')
var str = fs.readFileSync(file, 'utf-8')
var streamer = new StringStreamer(str)
var pdbParser = new PdbParser(streamer)
return pdbParser.parse().then(function (structure) {
var i = 0
structure.eachPolymer(function () {
i += 1
})
expect(i).toBe(3)
// import * as fs from 'fs'

import { promises as fsp } from 'fs'
import AtomProxy from '../../src/proxy/atom-proxy'

async function loadExample() {
const file = join(__dirname, '/../data/BaceCgProteinAtomistic.pdb')
const str = await fsp.readFile(file, 'utf-8')
const streamer = new StringStreamer(str)
const pdbParser = new PdbParser(streamer)
const structure = await pdbParser.parse()
return structure
}

describe('structure/structure', () => {
describe('iteration', () => {
test('structure identifies multiple polymers without chain info', async () => {
expect.assertions(1)
const structure = await loadExample()
let i = 0
structure.eachPolymer( () => { i++ } )
expect(i).toBe(3)
})
})

describe('updatePosition', () => {
test('bounding box updates and signals', async () => {
expect.assertions(6)
let signalCount = 0
const structure = await loadExample()

structure.signals.refreshed.add(() => {
signalCount++
})

const oldBoundingBox = structure.getBoundingBox()

const newCoords = new Float32Array(structure.atomCount * 3)
structure.eachAtom((ap: AtomProxy) => {
ap.positionToArray(newCoords, ap.index * 3)
})
newCoords.forEach((x, i) => {
newCoords[i] = x + 1
})

structure.updatePosition(newCoords, false) // false arg should prevent recalc of bounding box

expect(signalCount).toEqual(0)
expect(oldBoundingBox.min.equals(structure.boundingBox.min)).toBeTruthy()
expect(oldBoundingBox.max.equals(structure.boundingBox.max)).toBeTruthy()

structure.updatePosition(newCoords, true) // signal should fire and boundingBox should udpate

expect(signalCount).toEqual(1)
expect(oldBoundingBox.min.equals(structure.boundingBox.min)).toBeFalsy()
expect(oldBoundingBox.max.equals(structure.boundingBox.max)).toBeFalsy()
})
})
})


0 comments on commit 6be10a3

Please sign in to comment.