From d09167e26a3b7bdf918c435e08566d41aabba758 Mon Sep 17 00:00:00 2001 From: Maksim Imakaev Date: Tue, 10 Sep 2019 22:58:37 -0400 Subject: [PATCH 01/11] added draft of extrusion example --- examples/loopExtrusion/LEF_Dynamics.pyx | 190 ++++ examples/loopExtrusion/extrusion_1D.ipynb | 189 ++++ examples/loopExtrusion/extrusion_3D.ipynb | 315 ++++++ .../loopExtrusion/sample_contactmap.ipynb | 931 ++++++++++++++++++ polychrom/hdf5_format.py | 21 +- 5 files changed, 1640 insertions(+), 6 deletions(-) create mode 100644 examples/loopExtrusion/LEF_Dynamics.pyx create mode 100644 examples/loopExtrusion/extrusion_1D.ipynb create mode 100644 examples/loopExtrusion/extrusion_3D.ipynb create mode 100644 examples/loopExtrusion/sample_contactmap.ipynb diff --git a/examples/loopExtrusion/LEF_Dynamics.pyx b/examples/loopExtrusion/LEF_Dynamics.pyx new file mode 100644 index 0000000..420b97d --- /dev/null +++ b/examples/loopExtrusion/LEF_Dynamics.pyx @@ -0,0 +1,190 @@ +#!python +#cython: boundscheck=False +#cython: wraparound=False +#cython: initializedcheck=True + +import numpy as np +cimport numpy as np +import cython +cimport cython + + +cdef extern from "": + double drand48() + +cdef cython.double randnum(): + return drand48() + + +cdef class LEFTranslocatorDirectional(object): + cdef int N + cdef int M + cdef cython.double [:] emission + cdef cython.double [:] stallLeft + cdef cython.double [:] stallRight + cdef cython.double [:] stallFalloff + cdef cython.double [:] falloff + cdef cython.double [:] pause + cdef cython.double [:] cumEmission + cdef cython.long [:] LEFs1 + cdef cython.long [:] LEFs2 + cdef cython.long [:] stalled1 + cdef cython.long [:] stalled2 + cdef cython.long [:] occupied + + cdef int maxss + cdef int curss + cdef cython.long [:] ssarray + + + def __init__(self, emissionProb, deathProb, stallProbLeft, stallProbRight, pauseProb, stallFalloffProb, numLEF): + emissionProb[0] = 0 + emissionProb[len(emissionProb)-1] = 0 + emissionProb[stallProbLeft > 0.9] = 0 + emissionProb[stallProbRight > 0.9] = 0 + + self.N = len(emissionProb) + self.M = numLEF + self.emission = emissionProb + self.stallLeft = stallProbLeft + self.stallRight = stallProbRight + self.falloff = deathProb + self.pause = pauseProb + cumem = np.cumsum(emissionProb) + cumem = cumem / float(cumem[len(cumem)-1]) + self.cumEmission = np.array(cumem, np.double) + self.LEFs1 = np.zeros((self.M), int) + self.LEFs2 = np.zeros((self.M), int) + self.stalled1 = np.zeros(self.M, int) + self.stalled2 = np.zeros(self.M, int) + self.occupied = np.zeros(self.N, int) + self.stallFalloff = stallFalloffProb + self.occupied[0] = 1 + self.occupied[self.N - 1] = 1 + self.maxss = 1000000 + self.curss = 99999999 + + for ind in xrange(self.M): + self.birth(ind) + + + cdef birth(self, cython.int ind): + cdef int pos,i + + while True: + pos = self.getss() + if pos >= self.N - 1: + print "bad value", pos, self.cumEmission[len(self.cumEmission)-1] + continue + if pos <= 0: + print "bad value", pos, self.cumEmission[0] + continue + + + if self.occupied[pos] == 1: + continue + + self.LEFs1[ind] = pos + self.LEFs2[ind] = pos + self.occupied[pos] = 1 + + if (pos < (self.N - 3)) and (self.occupied[pos+1] == 0): + if randnum() > 0.5: + self.LEFs2[ind] = pos + 1 + self.occupied[pos+1] = 1 + + return + + cdef death(self): + cdef int i + cdef double falloff1, falloff2 + cdef double falloff + + for i in xrange(self.M): + if self.stalled1[i] == 0: + falloff1 = self.falloff[self.LEFs1[i]] + else: + falloff1 = self.stallFalloff[self.LEFs1[i]] + if self.stalled2[i] == 0: + falloff2 = self.falloff[self.LEFs2[i]] + else: + falloff2 = self.stallFalloff[self.LEFs2[i]] + + falloff = max(falloff1, falloff2) + if randnum() < falloff: + self.occupied[self.LEFs1[i]] = 0 + self.occupied[self.LEFs2[i]] = 0 + self.stalled1[i] = 0 + self.stalled2[i] = 0 + self.birth(i) + + cdef int getss(self): + + if self.curss >= self.maxss - 1: + foundArray = np.array(np.searchsorted(self.cumEmission, np.random.random(self.maxss)), dtype = np.long) + self.ssarray = foundArray + #print np.array(self.ssarray).min(), np.array(self.ssarray).max() + self.curss = -1 + + self.curss += 1 + return self.ssarray[self.curss] + + + + cdef step(self): + cdef int i + cdef double pause + cdef double stall1, stall2 + cdef int cur1 + cdef int cur2 + for i in range(self.M): + stall1 = self.stallLeft[self.LEFs1[i]] + stall2 = self.stallRight[self.LEFs2[i]] + + if randnum() < stall1: + self.stalled1[i] = 1 + if randnum() < stall2: + self.stalled2[i] = 1 + + + cur1 = self.LEFs1[i] + cur2 = self.LEFs2[i] + + if self.stalled1[i] == 0: + if self.occupied[cur1-1] == 0: + pause1 = self.pause[self.LEFs1[i]] + if randnum() > pause1: + self.occupied[cur1 - 1] = 1 + self.occupied[cur1] = 0 + self.LEFs1[i] = cur1 - 1 + if self.stalled2[i] == 0: + if self.occupied[cur2 + 1] == 0: + pause2 = self.pause[self.LEFs2[i]] + if randnum() > pause2: + self.occupied[cur2 + 1] = 1 + self.occupied[cur2] = 0 + self.LEFs2[i] = cur2 + 1 + + def steps(self,N): + cdef int i + for i in xrange(N): + self.death() + self.step() + + def getOccupied(self): + return np.array(self.occupied) + + def getLEFs(self): + return np.array(self.LEFs1), np.array(self.LEFs2) + + + def updateMap(self, cmap): + cmap[self.LEFs1, self.LEFs2] += 1 + cmap[self.LEFs2, self.LEFs1] += 1 + + def updatePos(self, pos, ind): + pos[ind, self.LEFs1] = 1 + pos[ind, self.LEFs2] = 1 + + + diff --git a/examples/loopExtrusion/extrusion_1D.ipynb b/examples/loopExtrusion/extrusion_1D.ipynb new file mode 100644 index 0000000..788e808 --- /dev/null +++ b/examples/loopExtrusion/extrusion_1D.ipynb @@ -0,0 +1,189 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import pickle\n", + "import os\n", + "import time\n", + "import numpy as np\n", + "import os \n", + "import shutil\n", + "\n", + "import pyximport; pyximport.install()\n", + "from LEF_Dynamics import LEFTranslocatorDirectional\n", + "\n", + "import warnings\n", + "import h5py \n", + "import glob" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Defining simulation parameters" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "# -------defining parameters----------\n", + "# -- basic loop extrusion parameters\n", + "SEPARATION = 200\n", + "LIFETIME = 300\n", + "N = 10000 # number of monomers\n", + "smcStepsPerBlock = 1 # now doing 1 SMC step per block \n", + "\n", + "trajectoryLength=100000\n", + "\n", + "\n", + "birthArray = np.zeros(N, dtype=np.double) + 0.1\n", + "deathArray = np.zeros(N, dtype=np.double) + 1. / LIFETIME\n", + "stallDeathArray = np.zeros(N, dtype=np.double) + 1 / LIFETIME\n", + "pauseArray = np.zeros(N, dtype=np.double)\n", + "\n", + "stallList = [1000, 3000, 5000, 7000, 9000]\n", + "stallLeftArray = np.zeros(N, dtype = np.double)\n", + "stallRightARray = np.zeros(N, dtype = np.double)\n", + "for i in stallList:\n", + " stallLeftArray[i] = 0.8\n", + " stallRightARray[i] = 0.8\n", + "\n", + "LEFNum = N // SEPARATION\n", + "LEFTran = LEFTranslocatorDirectional(birthArray, deathArray, stallLeftArray, stallRightARray, pauseArray,\n", + " stallDeathArray, LEFNum)\n", + "folder = \"trajectory\"\n", + "if not os.path.exists(folder):\n", + " os.mkdir(folder)\n", + " \n", + "with h5py.File(\"trajectory/LEFTrajectory.h5\", mode='w') as myfile:\n", + "\n", + " dset = myfile.create_dataset(\"trajectory\", \n", + " shape=(trajectoryLength, LEFNum, 2), \n", + " dtype=np.int32, \n", + " compression=\"gzip\")\n", + " steps = 50 \n", + " bins = np.linspace(0, trajectoryLength, steps, dtype=int)\n", + " for st,end in zip(bins[:-1], bins[1:]):\n", + " cur = []\n", + " for i in range(st, end):\n", + " LEFTran.steps(1)\n", + " LEFs = LEFTran.getLEFs()\n", + " cur.append(np.array(LEFs).T)\n", + " cur = np.array(cur)\n", + " dset[st:end] = cur\n", + " myfile.attrs[\"N\"] = N\n", + " myfile.attrs[\"LEFNum\"] = LEFNum\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[[9969, 9971],\n", + " [6563, 6565],\n", + " [2262, 2265],\n", + " ...,\n", + " [3704, 3707],\n", + " [2363, 2366],\n", + " [4974, 4977]],\n", + "\n", + " [[9968, 9972],\n", + " [6562, 6566],\n", + " [2261, 2266],\n", + " ...,\n", + " [3703, 3708],\n", + " [2362, 2367],\n", + " [4973, 4978]],\n", + "\n", + " [[9967, 9973],\n", + " [6562, 6567],\n", + " [2260, 2267],\n", + " ...,\n", + " [3702, 3709],\n", + " [2361, 2368],\n", + " [4972, 4979]],\n", + "\n", + " ...,\n", + "\n", + " [[7898, 7932],\n", + " [4903, 4984],\n", + " [1000, 2104],\n", + " ...,\n", + " [ 199, 465],\n", + " [ 32, 197],\n", + " [4756, 4796]],\n", + "\n", + " [[7898, 7933],\n", + " [4902, 4985],\n", + " [1000, 2104],\n", + " ...,\n", + " [ 199, 465],\n", + " [ 31, 197],\n", + " [4756, 4796]],\n", + "\n", + " [[7898, 7934],\n", + " [4901, 4986],\n", + " [1000, 2104],\n", + " ...,\n", + " [ 199, 465],\n", + " [ 30, 197],\n", + " [4756, 4796]]], dtype=int32)" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "with h5py.File(\"trajectory/LEFTrajectory.h5\", mode='r') as myfile:\n", + "\n", + " dset = myfile[\"trajectory\"][:]\n", + "dset" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/loopExtrusion/extrusion_3D.ipynb b/examples/loopExtrusion/extrusion_3D.ipynb new file mode 100644 index 0000000..e94276a --- /dev/null +++ b/examples/loopExtrusion/extrusion_3D.ipynb @@ -0,0 +1,315 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import pickle\n", + "import os\n", + "import time\n", + "import numpy as np\n", + "import polychrom\n", + "\n", + "from polychrom import polymerutils\n", + "from polychrom import forces\n", + "from polychrom import forcekits\n", + "from polychrom.simulation import Simulation\n", + "from polychrom.starting_conformations import grow_cubic\n", + "from polychrom.hdf5_format import HDF5Reporter, list_URIs, load_URI, load_hdf5_file\n", + "\n", + "import simtk.openmm \n", + "import os \n", + "import shutil\n", + "\n", + "\n", + "import warnings\n", + "import h5py \n", + "import glob" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Defining simulation parameters" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# -------defining parameters----------\n", + "# -- basic loop extrusion parameters\n", + "\n", + "folder = \"trajectory\"\n", + "\n", + "myfile = h5py.File(\"trajectory/LEFTrajectory.h5\", mode='r')\n", + "\n", + "N = myfile.attrs[\"N\"]\n", + "LEFNum = myfile.attrs[\"LEFNum\"]\n", + "traj = myfile[\"trajectory\"]\n", + "\n", + "Nframes = traj.shape[0]\n", + "\n", + " \n", + "steps = 250 # MD steps per step of cohesin\n", + "stiff = 1\n", + "dens = 0.1\n", + "box = (N / dens) ** 0.33 # density = 0.1.\n", + "data = grow_cubic(N, int(box) - 2) # creates a compact conformation \n", + "block = 0 # starting block \n", + "\n", + "# new parameters because some things changed \n", + "saveEveryBlocks = 10 # save every 10 blocks (saving every block is now too much almost)\n", + "restartSimulationEveryBlocks = 100\n", + "\n", + "# parameters for smc bonds\n", + "smcBondWiggleDist = 0.2\n", + "smcBondDist = 0.5\n", + "\n", + "# assertions for easy managing code below \n", + "assert (Nframes % restartSimulationEveryBlocks) == 0 \n", + "assert (restartSimulationEveryBlocks % saveEveryBlocks) == 0\n", + "\n", + "savesPerSim = restartSimulationEveryBlocks // saveEveryBlocks\n", + "simInitsTotal = (Nframes) // restartSimulationEveryBlocks" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Bond updating functions (for increased speed)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "class bondUpdater(object):\n", + "\n", + " def __init__(self, traj):\n", + " \"\"\"\n", + " :param smcTransObject: smc translocator object to work with\n", + " \"\"\"\n", + " self.trajectory = traj\n", + " self.curtime = 0\n", + " self.allBonds = []\n", + "\n", + " def setParams(self, activeParamDict, inactiveParamDict):\n", + " \"\"\"\n", + " A method to set parameters for bonds.\n", + " It is a separate method because you may want to have a Simulation object already existing\n", + "\n", + " :param activeParamDict: a dict (argument:value) of addBond arguments for active bonds\n", + " :param inactiveParamDict: a dict (argument:value) of addBond arguments for inactive bonds\n", + "\n", + " \"\"\"\n", + " self.activeParamDict = activeParamDict\n", + " self.inactiveParamDict = inactiveParamDict\n", + "\n", + "\n", + " def setup(self, bondForce, blocks=100, smcStepsPerBlock=1):\n", + " \"\"\"\n", + " A method that milks smcTranslocator object\n", + " and creates a set of unique bonds, etc.\n", + "\n", + " :param bondForce: a bondforce object (new after simulation restart!)\n", + " :param blocks: number of blocks to precalculate\n", + " :param smcStepsPerBlock: number of smcTranslocator steps per block\n", + " :return:\n", + " \"\"\"\n", + "\n", + "\n", + " if len(self.allBonds) != 0:\n", + " raise ValueError(\"Not all bonds were used; {0} sets left\".format(len(self.allBonds)))\n", + "\n", + " self.bondForce = bondForce\n", + "\n", + " #precalculating all bonds\n", + " allBonds = []\n", + " \n", + " loaded_trajectory = self.trajectory[self.curtime : self.curtime+blocks]\n", + " allBonds = [[(int(loaded_trajectory[i, j, 0]), int(loaded_trajectory[i, j, 1])) \n", + " for j in range(loaded_trajectory.shape[1])] for i in range(blocks)]\n", + "\n", + " self.allBonds = allBonds\n", + " self.uniqueBonds = list(set(sum(allBonds, [])))\n", + "\n", + " #adding forces and getting bond indices\n", + " self.bondInds = []\n", + " self.curBonds = allBonds.pop(0)\n", + "\n", + " for bond in self.uniqueBonds:\n", + " paramset = self.activeParamDict if (bond in self.curBonds) else self.inactiveParamDict\n", + " ind = bondForce.addBond(bond[0], bond[1], **paramset) # changed from addBond\n", + " self.bondInds.append(ind)\n", + " self.bondToInd = {i:j for i,j in zip(self.uniqueBonds, self.bondInds)}\n", + " \n", + " self.curtime += blocks \n", + " \n", + " return self.curBonds,[]\n", + "\n", + "\n", + " def step(self, context, verbose=False):\n", + " \"\"\"\n", + " Update the bonds to the next step.\n", + " It sets bonds for you automatically!\n", + " :param context: context\n", + " :return: (current bonds, previous step bonds); just for reference\n", + " \"\"\"\n", + " if len(self.allBonds) == 0:\n", + " raise ValueError(\"No bonds left to run; you should restart simulation and run setup again\")\n", + "\n", + " pastBonds = self.curBonds\n", + " self.curBonds = self.allBonds.pop(0) # getting current bonds\n", + " bondsRemove = [i for i in pastBonds if i not in self.curBonds]\n", + " bondsAdd = [i for i in self.curBonds if i not in pastBonds]\n", + " bondsStay = [i for i in pastBonds if i in self.curBonds]\n", + " if verbose:\n", + " print(\"{0} bonds stay, {1} new bonds, {2} bonds removed\".format(len(bondsStay),\n", + " len(bondsAdd), len(bondsRemove)))\n", + " bondsToChange = bondsAdd + bondsRemove\n", + " bondsIsAdd = [True] * len(bondsAdd) + [False] * len(bondsRemove)\n", + " for bond, isAdd in zip(bondsToChange, bondsIsAdd):\n", + " ind = self.bondToInd[bond]\n", + " paramset = self.activeParamDict if isAdd else self.inactiveParamDict\n", + " self.bondForce.setBondParameters(ind, bond[0], bond[1], **paramset) # actually updating bonds\n", + " self.bondForce.updateParametersInContext(context) # now run this to update things in the context\n", + " return self.curBonds, pastBonds" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Run simulation " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "milker = bondUpdater(traj)\n", + "\n", + "reporter = HDF5Reporter(folder=folder, max_data_length=100, overwrite=True, blocks_only=False)\n", + "\n", + "for iteration in range(simInitsTotal):\n", + " \n", + " # simulation parameters are defined below \n", + " a = Simulation(\n", + " platform=\"cuda\",\n", + " integrator=\"variableLangevin\", \n", + " error_tol=0.01, \n", + " GPU = \"0\", \n", + " collision_rate=0.03, \n", + " N = len(data),\n", + " reporters=[reporter],\n", + " PBCbox=[box, box, box],\n", + " precision=\"mixed\") # timestep not necessary for variableLangevin\n", + "\n", + " ############################## New code ##############################\n", + " a.set_data(data) # loads a polymer, puts a center of mass at zero\n", + " \n", + " a.add_force(\n", + " forcekits.polymer_chains(\n", + " a,\n", + " chains=[(0, None, None)],\n", + "\n", + " # By default the library assumes you have one polymer chain\n", + " # If you want to make it a ring, or more than one chain, use self.setChains\n", + " # self.setChains([(0,50,1),(50,None,0)]) will set a 50-monomer ring and a chain from monomer 50 to the end\n", + "\n", + " bond_force_func=forces.harmonic_bonds,\n", + " bond_force_kwargs={\n", + " 'bondLength':1.0,\n", + " 'bondWiggleDistance':0.1, # Bond distance will fluctuate +- 0.05 on average\n", + " },\n", + "\n", + " angle_force_func=forces.angle_force,\n", + " angle_force_kwargs={\n", + " 'k':0.05\n", + " # K is more or less arbitrary, k=4 corresponds to presistence length of 4,\n", + " # k=1.5 is recommended to make polymer realistically flexible; k=8 is very stiff\n", + " },\n", + "\n", + " nonbonded_force_func=forces.polynomial_repulsive,\n", + " nonbonded_force_kwargs={\n", + " 'trunc':1.5, # this will let chains cross sometimes\n", + " 'radiusMult':1.05, # this is from old code\n", + " #'trunc':10.0, # this will resolve chain crossings and will not let chain cross anymore\n", + " },\n", + "\n", + " except_bonds=True,\n", + " \n", + " )\n", + " )\n", + " \n", + " # ------------ initializing milker; adding bonds ---------\n", + " # copied from addBond\n", + " kbond = a.kbondScalingFactor / (smcBondWiggleDist ** 2)\n", + " bondDist = smcBondDist * a.length_scale\n", + "\n", + " activeParams = {\"length\":bondDist,\"k\":kbond}\n", + " inactiveParams = {\"length\":bondDist, \"k\":0}\n", + " milker.setParams(activeParams, inactiveParams)\n", + " \n", + " # this step actually puts all bonds in and sets first bonds to be what they should be\n", + " milker.setup(bondForce=a.force_dict['harmonic_bonds'],\n", + " blocks=restartSimulationEveryBlocks)\n", + "\n", + " # If your simulation does not start, consider using energy minimization below\n", + " if iteration==0:\n", + " a.local_energy_minimization() \n", + " else:\n", + " a._apply_forces()\n", + " \n", + " for i in range(restartSimulationEveryBlocks): \n", + " if i % saveEveryBlocks == (saveEveryBlocks - 1): \n", + " a.do_block(steps=steps)\n", + " else:\n", + " a.integrator.step(steps) # do steps without getting the positions from the GPU (faster)\n", + " if i < restartSimulationEveryBlocks - 1: \n", + " curBonds, pastBonds = milker.step(a.context) # this updates bonds. You can do something with bonds here\n", + " print(\"finished\")\n", + " data = a.get_data() # save data and step, and delete the simulation\n", + " del a\n", + " \n", + " reporter.blocks_only = True # Write output hdf5-files only for blocks\n", + "\n", + " time.sleep(0.2) # wait 200ms for sanity (to let garbage collector do its magic)\n", + " \n", + "reporter.dump_data()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/loopExtrusion/sample_contactmap.ipynb b/examples/loopExtrusion/sample_contactmap.ipynb new file mode 100644 index 0000000..c05a5c1 --- /dev/null +++ b/examples/loopExtrusion/sample_contactmap.ipynb @@ -0,0 +1,931 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [], + "source": [ + "from polychrom.hdf5_format import list_URIs, load_URI\n", + "\n", + "from polychrom.contactmaps import monomerResolutionContactMap" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(10000, 3)" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "URIs = list_URIs(\"trajectory/\")\n", + "load_URI(URIs[0])[\"pos\"].shape" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "code_folding": [], + "scrolled": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [], + "source": [ + "hmap = monomerResolutionContactMap(filenames=URIs, cutoff=8,\n", + " n=18, loadFunction=lambda x:load_URI(x)[\"pos\"])" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [], + "source": [ + "import seaborn as sns\n", + "import numpy as np\n", + "%matplotlib notebook" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [], + "source": [ + "from mirnylib.numutils import observedOverExpected" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/magus/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:1: RuntimeWarning: divide by zero encountered in log\n", + " \"\"\"Entry point for launching an IPython kernel.\n" + ] + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
');\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " event.shiftKey = false;\n", + " // Send a \"J\" for go to next cell\n", + " event.which = 74;\n", + " event.keyCode = 74;\n", + " manager.command_mode();\n", + " manager.handle_keydown(event);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\"\"\"\n", + "This cell is an example of verifying that everything is working \n", + "\"\"\"\n", + "SMCs = 2\n", + "args = {}\n", + "N = 200 \n", + "\n", + "\n", + "ctcfLeftRelease = {50:0.02}\n", + "ctcfRightRelease = {150:0.02}\n", + "ctcfLeftCapture = {50:0.5}\n", + "ctcfRightCapture = {150:0.5}\n", + "\n", + "args[\"ctcfRelease\"] = {-1:ctcfLeftRelease, 1:ctcfRightRelease}\n", + "args[\"ctcfCapture\"] = {-1:ctcfLeftCapture, 1:ctcfRightCapture} \n", + "args[\"N\"] = N \n", + "args[\"LIFETIME\"] = 100\n", + "args[\"LIFETIME_STALLED\"] = 10 \n", + "\n", + "\n", + "occupied = np.zeros(N)\n", + "occupied[0] = 1\n", + "occupied[-1] = 1 \n", + "cohesins = []\n", + "\n", + "\n", + "for i in range(SMCs):\n", + " loadOne(cohesins,occupied, args)\n", + "\n", + "\n", + "\n", + "def color(cohesins, args):\n", + " \"\"\"\n", + " A helper function that converts a list of cohesins to an array colored by cohesin state\n", + " \"\"\"\n", + " \n", + " def state(attrs):\n", + " if attrs[\"stalled\"]:\n", + " return 2\n", + " if attrs[\"CTCF\"]:\n", + " return 3\n", + " return 1\n", + " ar = np.zeros(args[\"N\"])\n", + " for i in cohesins:\n", + " ar[i.left.pos] = state(i.left.attrs)\n", + " ar[i.right.pos] = state(i.right.attrs) \n", + " return ar \n", + "\n", + "\n", + "pos = []\n", + "for i in range(300):\n", + " for _ in range(3):\n", + " translocate(cohesins, occupied, args)\n", + "\n", + " pos.append(color(cohesins, args))\n", + " \n", + "%matplotlib notebook\n", + "import matplotlib.pyplot as plt \n", + "plt.figure(figsize=(8,15))\n", + "plt.imshow(np.array(pos))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
');\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " event.shiftKey = false;\n", + " // Send a \"J\" for go to next cell\n", + " event.which = 74;\n", + " event.keyCode = 74;\n", + " manager.command_mode();\n", + " manager.handle_keydown(event);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ + "SMCs = 2\n", + "args = {}\n", + "N = 200 # two SMCs in a 200-monomer long simulation \n", "\n", - "# -------defining parameters----------\n", - "# -- basic loop extrusion parameters\n", - "SEPARATION = 200\n", - "LIFETIME = 300\n", - "N = 10000 # number of monomers\n", - "smcStepsPerBlock = 1 # now doing 1 SMC step per block \n", + "ctcfLeftCapture = {50:0.5} # at position 50 we have a CTCF that travelling left with 50% prob\n", + "ctcfRightCapture = {150:0.5} # and at 150 - those travelling right \n", + "ctcfLeftRelease = {50:0.02} # and we release them with 0.02 probability each step (on average 50 step residence time)\n", + "ctcfRightRelease = {150:0.02} \n", "\n", - "trajectoryLength=100000\n", + "args[\"ctcfRelease\"] = {-1:ctcfLeftRelease, 1:ctcfRightRelease} # this is how we feed the dictionaries of capture/release probabilities to our code \n", + "args[\"ctcfCapture\"] = {-1:ctcfLeftCapture, 1:ctcfRightCapture} \n", + "args[\"N\"] = N \n", + "args[\"LIFETIME\"] = 100\n", + "args[\"LIFETIME_STALLED\"] = 10 # in this code, if you are stalled, you have 10 times lower lifetime \n", + "# but if you are stalled at CTCF, you don't \n", + "# try to find this in the image below and verify that it works\n", "\n", + "occupied = np.zeros(N)\n", + "occupied[0] = 1\n", + "occupied[-1] = 1 \n", + "cohesins = []\n", "\n", - "birthArray = np.zeros(N, dtype=np.double) + 0.1\n", - "deathArray = np.zeros(N, dtype=np.double) + 1. / LIFETIME\n", - "stallDeathArray = np.zeros(N, dtype=np.double) + 1 / LIFETIME\n", - "pauseArray = np.zeros(N, dtype=np.double)\n", + "for i in range(SMCs):\n", + " loadOne(cohesins,occupied, args)\n", "\n", - "stallList = [1000, 3000, 5000, 7000, 9000]\n", - "stallLeftArray = np.zeros(N, dtype = np.double)\n", - "stallRightARray = np.zeros(N, dtype = np.double)\n", - "for i in stallList:\n", - " stallLeftArray[i] = 0.8\n", - " stallRightARray[i] = 0.8\n", - "\n", - "LEFNum = N // SEPARATION\n", - "LEFTran = LEFTranslocatorDirectional(birthArray, deathArray, stallLeftArray, stallRightARray, pauseArray,\n", - " stallDeathArray, LEFNum)\n", - "folder = \"trajectory\"\n", - "if not os.path.exists(folder):\n", - " os.mkdir(folder)\n", + "pos = []\n", + "for i in range(300):\n", + " for _ in range(3):\n", + " translocate(cohesins, occupied, args)\n", + " pos.append(color(cohesins, args))\n", " \n", - "with h5py.File(\"trajectory/LEFTrajectory.h5\", mode='w') as myfile:\n", - "\n", - " dset = myfile.create_dataset(\"trajectory\", \n", - " shape=(trajectoryLength, LEFNum, 2), \n", - " dtype=np.int32, \n", - " compression=\"gzip\")\n", - " steps = 50 \n", - " bins = np.linspace(0, trajectoryLength, steps, dtype=int)\n", - " for st,end in zip(bins[:-1], bins[1:]):\n", - " cur = []\n", - " for i in range(st, end):\n", - " LEFTran.steps(1)\n", - " LEFs = LEFTran.getLEFs()\n", - " cur.append(np.array(LEFs).T)\n", - " cur = np.array(cur)\n", - " dset[st:end] = cur\n", - " myfile.attrs[\"N\"] = N\n", - " myfile.attrs[\"LEFNum\"] = LEFNum\n", - "\n", - "\n" + "%matplotlib notebook\n", + "import matplotlib.pyplot as plt \n", + "plt.figure(figsize=(8,15))\n", + "plt.imshow(np.array(pos))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## This will be a full-scale simulation, but we're going to visualize some trajectory first " ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 3, "metadata": {}, "outputs": [ { "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
');\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", - " button.click(method_name, toolbar_event);\n", - " button.mouseover(tooltip, toolbar_mouse_event);\n", - " nav_element.append(button);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = $('');\n", - " nav_element.append(status_bar);\n", - " this.message = status_bar[0];\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = $('
');\n", - " var button = $('');\n", - " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", - " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", - " buttongrp.append(button);\n", - " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", - " titlebar.prepend(buttongrp);\n", - "}\n", - "\n", - "mpl.figure.prototype._root_extra_style = function(el){\n", - " var fig = this\n", - " el.on(\"remove\", function(){\n", - "\tfig.close_ws(fig, {});\n", - " });\n", - "}\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function(el){\n", - " // this is important to make the div 'focusable\n", - " el.attr('tabindex', 0)\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " }\n", - " else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "\n", - "}\n", - "\n", - "mpl.figure.prototype._key_event_extra = function(event, name) {\n", - " var manager = IPython.notebook.keyboard_manager;\n", - " if (!manager)\n", - " manager = IPython.keyboard_manager;\n", - "\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which == 13) {\n", - " this.canvas_div.blur();\n", - " event.shiftKey = false;\n", - " // Send a \"J\" for go to next cell\n", - " event.which = 74;\n", - " event.keyCode = 74;\n", - " manager.command_mode();\n", - " manager.handle_keydown(event);\n", - " }\n", - "}\n", - "\n", - "mpl.figure.prototype.handle_save = function(fig, msg) {\n", - " fig.ondownload(fig, null);\n", - "}\n", - "\n", - "\n", - "mpl.find_output_cell = function(html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] == html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "}\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel != null) {\n", - " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "SMCs = 2\n", - "args = {}\n", - "N = 200 # two SMCs in a 200-monomer long simulation \n", - "\n", - "ctcfLeftCapture = {50:0.5} # at position 50 we have a CTCF that travelling left with 50% prob\n", - "ctcfRightCapture = {150:0.5} # and at 150 - those travelling right \n", - "ctcfLeftRelease = {50:0.02} # and we release them with 0.02 probability each step (on average 50 step residence time)\n", - "ctcfRightRelease = {150:0.02} \n", - "\n", - "args[\"ctcfRelease\"] = {-1:ctcfLeftRelease, 1:ctcfRightRelease} # this is how we feed the dictionaries of capture/release probabilities to our code \n", - "args[\"ctcfCapture\"] = {-1:ctcfLeftCapture, 1:ctcfRightCapture} \n", - "args[\"N\"] = N \n", - "args[\"LIFETIME\"] = 100\n", - "args[\"LIFETIME_STALLED\"] = 10 # in this code, if you are stalled, you have 10 times lower lifetime \n", - "# but if you are stalled at CTCF, you don't \n", - "# try to find this in the image below and verify that it works\n", - "\n", - "occupied = np.zeros(N)\n", - "occupied[0] = 1\n", - "occupied[-1] = 1 \n", - "cohesins = []\n", - "\n", - "for i in range(SMCs):\n", - " loadOne(cohesins,occupied, args)\n", - "\n", - "pos = []\n", - "for i in range(300):\n", - " for _ in range(3):\n", - " translocate(cohesins, occupied, args)\n", - " pos.append(color(cohesins, args))\n", - " \n", - "%matplotlib notebook\n", - "import matplotlib.pyplot as plt \n", - "plt.figure(figsize=(8,15))\n", - "plt.imshow(np.array(pos))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## This will be a full-scale simulation, but we're going to visualize some trajectory first " - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "window.mpl = {};\n", - "\n", - "\n", - "mpl.get_websocket_type = function() {\n", - " if (typeof(WebSocket) !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof(MozWebSocket) !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert('Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.');\n", - " };\n", - "}\n", - "\n", - "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = (this.ws.binaryType != undefined);\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById(\"mpl-warnings\");\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent = (\n", - " \"This browser does not support binary websocket messages. \" +\n", - " \"Performance may be slow.\");\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = $('
');\n", - " this._root_extra_style(this.root)\n", - " this.root.attr('style', 'display: inline-block');\n", - "\n", - " $(parent_element).append(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", - " fig.send_message(\"send_image_mode\", {});\n", - " if (mpl.ratio != 1) {\n", - " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", - " }\n", - " fig.send_message(\"refresh\", {});\n", - " }\n", - "\n", - " this.imageObj.onload = function() {\n", - " if (fig.image_mode == 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function() {\n", - " fig.ws.close();\n", - " }\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "}\n", - "\n", - "mpl.figure.prototype._init_header = function() {\n", - " var titlebar = $(\n", - " '
');\n", - " var titletext = $(\n", - " '
');\n", - " titlebar.append(titletext)\n", - " this.root.append(titlebar);\n", - " this.header = titletext[0];\n", - "}\n", - "\n", - "\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", - "\n", - "}\n", - "\n", - "\n", - "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", - "\n", - "}\n", - "\n", - "mpl.figure.prototype._init_canvas = function() {\n", - " var fig = this;\n", - "\n", - " var canvas_div = $('
');\n", - "\n", - " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", - "\n", - " function canvas_keyboard_event(event) {\n", - " return fig.key_event(event, event['data']);\n", - " }\n", - "\n", - " canvas_div.keydown('key_press', canvas_keyboard_event);\n", - " canvas_div.keyup('key_release', canvas_keyboard_event);\n", - " this.canvas_div = canvas_div\n", - " this._canvas_extra_style(canvas_div)\n", - " this.root.append(canvas_div);\n", - "\n", - " var canvas = $('');\n", - " canvas.addClass('mpl-canvas');\n", - " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", - "\n", - " this.canvas = canvas[0];\n", - " this.context = canvas[0].getContext(\"2d\");\n", - "\n", - " var backingStore = this.context.backingStorePixelRatio ||\n", - "\tthis.context.webkitBackingStorePixelRatio ||\n", - "\tthis.context.mozBackingStorePixelRatio ||\n", - "\tthis.context.msBackingStorePixelRatio ||\n", - "\tthis.context.oBackingStorePixelRatio ||\n", - "\tthis.context.backingStorePixelRatio || 1;\n", - "\n", - " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband = $('');\n", - " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", - "\n", - " var pass_mouse_events = true;\n", - "\n", - " canvas_div.resizable({\n", - " start: function(event, ui) {\n", - " pass_mouse_events = false;\n", - " },\n", - " resize: function(event, ui) {\n", - " fig.request_resize(ui.size.width, ui.size.height);\n", - " },\n", - " stop: function(event, ui) {\n", - " pass_mouse_events = true;\n", - " fig.request_resize(ui.size.width, ui.size.height);\n", - " },\n", - " });\n", - "\n", - " function mouse_event_fn(event) {\n", - " if (pass_mouse_events)\n", - " return fig.mouse_event(event, event['data']);\n", - " }\n", - "\n", - " rubberband.mousedown('button_press', mouse_event_fn);\n", - " rubberband.mouseup('button_release', mouse_event_fn);\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " rubberband.mousemove('motion_notify', mouse_event_fn);\n", - "\n", - " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", - " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", - "\n", - " canvas_div.on(\"wheel\", function (event) {\n", - " event = event.originalEvent;\n", - " event['data'] = 'scroll'\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " mouse_event_fn(event);\n", - " });\n", - "\n", - " canvas_div.append(canvas);\n", - " canvas_div.append(rubberband);\n", - "\n", - " this.rubberband = rubberband;\n", - " this.rubberband_canvas = rubberband[0];\n", - " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", - " this.rubberband_context.strokeStyle = \"#000000\";\n", - "\n", - " this._resize_canvas = function(width, height) {\n", - " // Keep the size of the canvas, canvas container, and rubber band\n", - " // canvas in synch.\n", - " canvas_div.css('width', width)\n", - " canvas_div.css('height', height)\n", - "\n", - " canvas.attr('width', width * mpl.ratio);\n", - " canvas.attr('height', height * mpl.ratio);\n", - " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", - "\n", - " rubberband.attr('width', width);\n", - " rubberband.attr('height', height);\n", - " }\n", - "\n", - " // Set the figure to an initial 600x600px, this will subsequently be updated\n", - " // upon first draw.\n", - " this._resize_canvas(600, 600);\n", - "\n", - " // Disable right mouse context menu.\n", - " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", - " return false;\n", - " });\n", - "\n", - " function set_focus () {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "}\n", - "\n", - "mpl.figure.prototype._init_toolbar = function() {\n", - " var fig = this;\n", - "\n", - " var nav_element = $('
');\n", - " nav_element.attr('style', 'width: 100%');\n", - " this.root.append(nav_element);\n", - "\n", - " // Define a callback function for later on.\n", - " function toolbar_event(event) {\n", - " return fig.toolbar_button_onclick(event['data']);\n", - " }\n", - " function toolbar_mouse_event(event) {\n", - " return fig.toolbar_button_onmouseover(event['data']);\n", - " }\n", - "\n", - " for(var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " // put a spacer in here.\n", - " continue;\n", - " }\n", - " var button = $('