cellbrowser 1.2.20__tar.gz → 1.2.22__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cellbrowser-1.2.20/src/cbPyLib/cellbrowser.egg-info → cellbrowser-1.2.22}/PKG-INFO +1 -1
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/R/cellbrowser.R +31 -16
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/_version.py +3 -3
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/css/cellBrowser.css +308 -9
- cellbrowser-1.2.22/src/cbPyLib/cellbrowser/cbWeb/genes/makeMgiIds.py +60 -0
- cellbrowser-1.2.22/src/cbPyLib/cellbrowser/cbWeb/genes/mgiIds-8Dec17.json +1 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/js/cbData.js +99 -14
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/js/cellBrowser.js +3343 -187
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/js/maxHeat.js +17 -9
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/js/maxPlot.js +385 -43
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cellbrowser.py +465 -20
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/convert.py +7 -7
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/geneinfo.py +204 -62
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/sampleConfig/cellbrowser.conf +9 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/seurat.py +22 -12
- {cellbrowser-1.2.20 → cellbrowser-1.2.22/src/cbPyLib/cellbrowser.egg-info}/PKG-INFO +1 -1
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser.egg-info/SOURCES.txt +2 -2
- cellbrowser-1.2.20/src/cbPyLib/cellbrowser/bw_genes.py +0 -624
- cellbrowser-1.2.20/src/cbPyLib/cellbrowser/cbWeb/ext/font-awesome.css +0 -1479
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/LICENSE +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/MANIFEST.in +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/README.rst +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/setup.cfg +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/setup.py +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/RangeHTTPServer/__init__.py +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/RangeHTTPServer/__main__.py +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/__init__.py +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/css/MaterialIcons-Regular.eot +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/css/MaterialIcons-Regular.ttf +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/css/MaterialIcons-Regular.woff +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/css/MaterialIcons-Regular.woff2 +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/css/darkMode-claude.css +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/css/darkMode.css +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/Chart.bundle.min.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/FastBitSet.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/FileSaver.1.1.20151003.min.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/OverlayScrollbars.min.css +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/bootstrap-dropmenu.min.css +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/bootstrap-submenu.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/bootstrap-submenu.min.css +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/bootstrap.3.3.7.min.css +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/bootstrap.min.css +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/bootstrap.min.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/chartjs-chart-box-and-violin-plot.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/chosen-sprite.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/chosen-sprite@2x.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/chosen.1.8.2.min.css +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/chosen.jquery.min.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/drawImage-clipper.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/googleMaterialIcons.css +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/hamster.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/images/ui-icons_444444_256x240.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/images/ui-icons_555555_256x240.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/images/ui-icons_777620_256x240.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/images/ui-icons_777777_256x240.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/images/ui-icons_cc0000_256x240.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/images/ui-icons_ffffff_256x240.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/intro.min.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/introjs.2.4.0.min.css +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/jquery-ui-1.12.1.css +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/jquery-ui.min.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/jquery.3.1.1.min.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/jquery.contextMenu.css +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/jquery.contextMenu.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/jquery.event.drag-2.3.0.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/jquery.overlayScrollbars.min.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/jquery.sparkline.min.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/jquery.tablesorter.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/jquery.tablesorter.widgets.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/jquery.tipsy.1.0.3.min.css +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/jquery.tipsy.min.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/jquery.ui.position.min.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/jsurl2.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/lz-string.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/materialIcons.woff +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/minified.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/minisearch.min.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/mousetrap.min.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/normalizeWheel.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/pako_inflate.min.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/palette.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/papaparse.min.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/reorder.v1.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/scaleColorPerceptual.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/science.v1.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/select2.4.0.4.min.css +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/select2.min.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/selectize.bootstrap3.css +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/selectize.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/slick.cellrangedecorator.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/slick.cellrangeselector.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/slick.cellselectionmodel.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/slick.core.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/slick.editors.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/slick.examples.css +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/slick.formatters.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/slick.grid.css +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/slick.grid.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/spectrum-1.8.0.css +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/spectrum.min.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/split.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/tablesort.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/tablesort.number.min.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/.npmignore +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/LICENSE +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/Makefile +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/README.md +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/browser.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/build.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/example/d3-random-matrix.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/example/example.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/example/gradients.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/example/package.json +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/hex/inferno.json +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/hex/magma.json +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/hex/plasma.json +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/hex/viridis.json +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/inferno.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/magma.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/package.json +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/plasma.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/rgb/inferno.json +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/rgb/magma.json +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/rgb/plasma.json +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/rgb/viridis.json +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/utils/hex2rgb.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/utils/interpolate.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/utils/rgb2hex.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/viridis.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/theme.bootstrap_3.css +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/ext/tiny-queue.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/genes/files.json +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/genes/hg19.gc34.tsv +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/genes/hg19.json.gz +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/genes/hg38.gc34.tsv +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/genes/hg38.json.gz +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/genes/log.txt +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/genes/makeGenes.py +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/genes/mm10.json.gz +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/genes/mm10.vm25.tsv +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/README.md +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/center.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/README.txt +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/gtk-justify-left.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/gtk-save.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/log.txt +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-center-16.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-center-24.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-controller-16.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-controller-24.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-edit-16.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-gravity-west-24.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-info-16.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-info-24.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-merge-down-16.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-scale-16.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-tool-free-select-16.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-tool-free-select-22.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-tool-move-16.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-tool-move-22.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-tool-rect-select-16.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-tool-rect-select-22.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-tool-zoom-16.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-tool-zoom-22.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/icons8-help-32.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/info.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/lasso.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/marker.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/move.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/select.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/img/zoom.png +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/cbWeb/js/violinWorker.js +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/download.py +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/genes.py +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/hubmaker.py +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/sampleConfig/desc.conf +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/sampleConfig/hub.conf +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/sampleConfig/scanpy.conf +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/sampleConfig/seurat.conf +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser/sampleConfig/summary.html +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser.egg-info/dependency_links.txt +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser.egg-info/entry_points.txt +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser.egg-info/not-zip-safe +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/src/cbPyLib/cellbrowser.egg-info/top_level.txt +0 -0
- {cellbrowser-1.2.20 → cellbrowser-1.2.22}/versioneer.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: cellbrowser
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.22
|
|
4
4
|
Summary: UCSC Cellbrowser, an interactive browser for single cell data. Includes converters and basic pipelines for text files, Seurat, Scanpy and Cellranger.
|
|
5
5
|
Home-page: https://github.com/maximilianh/cellBrowser
|
|
6
6
|
Author: Maximilian Haeussler
|
|
@@ -386,7 +386,14 @@ ExportToCellbrowser <- function(
|
|
|
386
386
|
#}
|
|
387
387
|
#}
|
|
388
388
|
if (is.null(x = cluster.field)) {
|
|
389
|
-
|
|
389
|
+
# Do not stop here: loading the object is often the slowest step. Export everything
|
|
390
|
+
# that does not need a cluster field, skip the markers, and leave the cluster lines in
|
|
391
|
+
# cellbrowser.conf commented out with the possible fields listed, for the user to fill in.
|
|
392
|
+
warning("No cluster field was given (cluster.field='xxx' from R or -c xxx with cbImportSeurat). ",
|
|
393
|
+
"Exporting everything else, but no cluster markers will be computed. Possible meta annotation fields are: ",
|
|
394
|
+
toString(colnames(x = meta)), immediate. = TRUE)
|
|
395
|
+
if (is.null(markers.file))
|
|
396
|
+
skip.markers <- TRUE
|
|
390
397
|
# create a new meta data field named "Cluster"
|
|
391
398
|
#newDf <- cbind(object@meta.data, Idents(object))
|
|
392
399
|
# default name is "Idents(object)", not good, let's rename that to "Cluster"
|
|
@@ -400,10 +407,6 @@ ExportToCellbrowser <- function(
|
|
|
400
407
|
#Idents(object) <- as.factor([object[[cluster.field]], cluster.field])
|
|
401
408
|
}
|
|
402
409
|
|
|
403
|
-
# make sure that we have a cluster field
|
|
404
|
-
#if (is.null(x = cluster.field))
|
|
405
|
-
#stop("There was no cluster field provided and the auto-detection to find one based on Idents() did not work. Please provide a cluster field with cluster.field='xxx' from R or --clusterField=xxx if using cbImportSeurat. Possible meta annotation fields are: ", toString(colnames(x = meta)))
|
|
406
|
-
|
|
407
410
|
if (is.null(x = meta.fields)) {
|
|
408
411
|
meta.fields <- colnames(x = meta)
|
|
409
412
|
#if (length(x = levels(x = Idents(object))) > 1) {
|
|
@@ -582,7 +585,7 @@ ExportToCellbrowser <- function(
|
|
|
582
585
|
}
|
|
583
586
|
if (!is.null(file)) {
|
|
584
587
|
markers.string <- sprintf(
|
|
585
|
-
'markers = [{"file": "%s", "shortLabel": "
|
|
588
|
+
'markers = [{"file": "%s", "shortLabel": "Cluster Markers"}]',
|
|
586
589
|
file
|
|
587
590
|
)
|
|
588
591
|
}
|
|
@@ -602,15 +605,19 @@ ExportToCellbrowser <- function(
|
|
|
602
605
|
matrixLabels <- matrixNames
|
|
603
606
|
matrixLabels[matrixLabels=="counts"] <- "read counts"
|
|
604
607
|
matrixLabels[matrixLabels=="scale.data"] <- "scaled"
|
|
605
|
-
|
|
606
|
-
|
|
608
|
+
# saveMatrix() writes <prefix>matrix.mtx.gz in MTX mode, <prefix>exprMatrix.tsv.gz otherwise.
|
|
609
|
+
# use.mtx may also have been switched on above for big matrices, so both file names follow it.
|
|
610
|
+
matrixFileEnd <- "exprMatrix.tsv.gz"
|
|
611
|
+
if (use.mtx) {
|
|
612
|
+
matrixFileEnd <- "matrix.mtx.gz"
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
matrices.conf <- sprintf(" {'label':'%s','fileName':'%s_%s'}",
|
|
616
|
+
names(slotMatrices), names(slotMatrices), matrixFileEnd)
|
|
607
617
|
|
|
608
618
|
matrices.string <- paste0("matrices=[", paste(matrices.conf, collapse = ",\n"), "]" )
|
|
609
619
|
|
|
610
|
-
matrixOutPath <- sprintf("%s%
|
|
611
|
-
if (use.mtx) {
|
|
612
|
-
matrixOutPath <- sprintf("%s%smatrix.mtx.gz", firstPrefix, matSep)
|
|
613
|
-
}
|
|
620
|
+
matrixOutPath <- sprintf("%s%s%s", firstPrefix, matSep, matrixFileEnd)
|
|
614
621
|
|
|
615
622
|
embeddings.conf <- exportImages(object, dir, embeddings.conf)
|
|
616
623
|
|
|
@@ -628,8 +635,7 @@ meta="meta.tsv"
|
|
|
628
635
|
geneIdType="auto"
|
|
629
636
|
# file with gene,description (one per line) with highlighted genes, called "Dataset Genes" in the user interface
|
|
630
637
|
# quickGenesFile="quickGenes.csv"
|
|
631
|
-
|
|
632
|
-
labelField="%s"
|
|
638
|
+
%s
|
|
633
639
|
enumFields=%s
|
|
634
640
|
%s
|
|
635
641
|
coords=%s
|
|
@@ -641,13 +647,22 @@ coords=%s
|
|
|
641
647
|
|
|
642
648
|
coords.string <- paste0( "[", paste(embeddings.conf, collapse = ",\n"), "]" )
|
|
643
649
|
|
|
650
|
+
# a NULL cluster.field passed to sprintf() would make the whole config come out empty
|
|
651
|
+
if (is.null(x = cluster.field)) {
|
|
652
|
+
cluster.string <- paste0(
|
|
653
|
+
"# No cluster field was given to cbImportSeurat. Uncomment these two lines and set them to one of:\n# ",
|
|
654
|
+
toString(colnames(x = meta)), "\n",
|
|
655
|
+
'#clusterField="CHANGE_ME"\n#labelField="CHANGE_ME"')
|
|
656
|
+
} else {
|
|
657
|
+
cluster.string <- sprintf('clusterField="%s"\nlabelField="%s"', cluster.field, cluster.field)
|
|
658
|
+
}
|
|
659
|
+
|
|
644
660
|
config <- sprintf(
|
|
645
661
|
config,
|
|
646
662
|
dataset.name,
|
|
647
663
|
matrixOutPath,
|
|
648
664
|
matrices.string,
|
|
649
|
-
cluster.
|
|
650
|
-
cluster.field,
|
|
665
|
+
cluster.string,
|
|
651
666
|
enum.string,
|
|
652
667
|
markers.string,
|
|
653
668
|
coords.string
|
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2026-
|
|
11
|
+
"date": "2026-10-30T20:38:46-0700",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "1.2.
|
|
14
|
+
"full-revisionid": "cf49415184a7f13f66566c4137051f700c29e5b9",
|
|
15
|
+
"version": "1.2.22"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -13,18 +13,42 @@ section { font-weight: bold; padding-top: 5px; padding-bottom: 5px }
|
|
|
13
13
|
/*border-bottom: 1px solid black; */
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
/* fixed to the window and filling all of it: the page underneath can be a few pixels taller
|
|
17
|
+
* than the window, and a box positioned on the page scrolled with it and showed a strip below.
|
|
18
|
+
* The title bar and the controls stay put, only #tpExprViewPlot scrolls. */
|
|
16
19
|
#tpExprView {
|
|
17
|
-
position:
|
|
20
|
+
position: fixed;
|
|
18
21
|
z-index: 600;
|
|
19
|
-
display:
|
|
22
|
+
display: flex;
|
|
23
|
+
flex-direction: column;
|
|
20
24
|
background-color: white;
|
|
21
|
-
top:
|
|
22
|
-
left:
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
top: 0;
|
|
26
|
+
left: 0;
|
|
27
|
+
right: 0;
|
|
28
|
+
bottom: 0;
|
|
29
|
+
overflow: hidden;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/* dot plot hover box, see exprTipShow() */
|
|
33
|
+
#tpExprTip {
|
|
34
|
+
display: none;
|
|
35
|
+
position: fixed;
|
|
36
|
+
z-index: 700;
|
|
37
|
+
pointer-events: none;
|
|
38
|
+
white-space: nowrap;
|
|
39
|
+
background-color: white;
|
|
40
|
+
color: black;
|
|
41
|
+
border: 1px solid #aaa;
|
|
42
|
+
border-radius: 4px;
|
|
43
|
+
box-shadow: 0 2px 6px rgba(0,0,0,0.2);
|
|
44
|
+
padding: 6px 9px;
|
|
45
|
+
font-size: 13px;
|
|
46
|
+
line-height: 1.4;
|
|
27
47
|
}
|
|
48
|
+
.tpExprTipTitle { font-weight: bold; font-size: 14px; }
|
|
49
|
+
|
|
50
|
+
/* the hovered dot's row label and gene name */
|
|
51
|
+
#tpExprDotPlot .tpExprHi { font-weight: bold; fill: #1a5fb4; }
|
|
28
52
|
|
|
29
53
|
#tpExprViewHeader {
|
|
30
54
|
display: flex;
|
|
@@ -35,6 +59,12 @@ section { font-weight: bold; padding-top: 5px; padding-bottom: 5px }
|
|
|
35
59
|
padding-bottom: 6px;
|
|
36
60
|
}
|
|
37
61
|
|
|
62
|
+
/* dot plot controls while a load is running, see exprSetBusy() */
|
|
63
|
+
#tpExprViewHeader.tpExprBusy {
|
|
64
|
+
opacity: 0.5;
|
|
65
|
+
pointer-events: none;
|
|
66
|
+
}
|
|
67
|
+
|
|
38
68
|
.hasTooltip {
|
|
39
69
|
display: inline-flex;
|
|
40
70
|
align-items: center;
|
|
@@ -110,24 +140,51 @@ section { font-weight: bold; padding-top: 5px; padding-bottom: 5px }
|
|
|
110
140
|
|
|
111
141
|
.tpExprHeaderRow { display: flex; align-items: center; gap: 8px; flex-basis: 100%; }
|
|
112
142
|
.tpExprFilterWrap { position: relative; display: inline-block; }
|
|
143
|
+
/* sits immediately left of the "All" button on the split/subsplit rows, so the
|
|
144
|
+
* button reads as a filter rather than an unlabelled dropdown */
|
|
145
|
+
.tpExprFilterLabel { margin-bottom: 0; margin-left: 6px; }
|
|
113
146
|
.tpExprFilterBtn { height: 25px; font-size: 13px; border: 1px solid #ccc; background: white; cursor: pointer; padding: 0 8px; border-radius: 3px; }
|
|
114
147
|
.tpExprFilterPanel { position: absolute; top: 27px; left: 0; background: white; border: 1px solid #ccc; border-radius: 3px; z-index: 10001; padding: 4px 8px; max-height: 220px; overflow-y: auto; min-width: 150px; box-shadow: 0 2px 6px rgba(0,0,0,0.15); }
|
|
115
148
|
.tpExprFilterItem label { display: block; padding: 1px 0; cursor: pointer; white-space: nowrap; font-size: 13px; }
|
|
116
149
|
.tpExprFilterAll { border-bottom: 1px solid #eee; margin-bottom: 4px; padding-bottom: 3px; font-size: 13px; }
|
|
117
150
|
#tpGeneExprSubsplitLabel { margin-left: 6px; margin-right: 6px; margin-bottom: 0; }
|
|
118
151
|
|
|
152
|
+
/* takes the space below the controls and scrolls both ways, so a dot plot with many genes or rows
|
|
153
|
+
* can be scrolled while the controls above it stay in view */
|
|
119
154
|
#tpExprViewPlot {
|
|
120
155
|
display:flex;
|
|
121
156
|
flex-direction: row;
|
|
122
157
|
flex-flow: wrap;
|
|
158
|
+
align-items: flex-start;
|
|
159
|
+
align-content: flex-start;
|
|
123
160
|
padding-top:10px;
|
|
161
|
+
flex: 1;
|
|
162
|
+
min-height: 0;
|
|
163
|
+
overflow: auto;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/* a flex item can shrink, so a dot plot with many genes was squeezed to the window width and its
|
|
167
|
+
* right side cut off. Keep its full width so #tpExprViewPlot can scroll sideways instead. */
|
|
168
|
+
#tpExprViewPlot > svg {
|
|
169
|
+
flex-shrink: 0;
|
|
124
170
|
}
|
|
125
171
|
|
|
126
172
|
#tpExprViewContent {
|
|
127
173
|
padding: 6px;
|
|
174
|
+
flex: 1;
|
|
175
|
+
min-height: 0;
|
|
176
|
+
display: flex;
|
|
177
|
+
flex-direction: column;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
#tpExprPerturbRow label {
|
|
181
|
+
margin-left: 6px;
|
|
182
|
+
margin-right: 6px;
|
|
183
|
+
margin-bottom: 0;
|
|
128
184
|
}
|
|
129
185
|
|
|
130
186
|
#tpGeneExprLabel {
|
|
187
|
+
margin-left: 6px;
|
|
131
188
|
margin-right: 6px;
|
|
132
189
|
margin-bottom: 0;
|
|
133
190
|
}
|
|
@@ -337,8 +394,14 @@ section { font-weight: bold; padding-top: 5px; padding-bottom: 5px }
|
|
|
337
394
|
}
|
|
338
395
|
.progress-label {
|
|
339
396
|
position: absolute;
|
|
340
|
-
left:
|
|
397
|
+
left: 0;
|
|
398
|
+
right: 0;
|
|
341
399
|
top: 4px;
|
|
400
|
+
padding: 0 8px;
|
|
401
|
+
text-align: center;
|
|
402
|
+
white-space: nowrap;
|
|
403
|
+
overflow: hidden;
|
|
404
|
+
text-overflow: ellipsis;
|
|
342
405
|
font-weight: bold;
|
|
343
406
|
/*text-shadow: 1px 1px 0 #fff;*/
|
|
344
407
|
}
|
|
@@ -847,3 +910,239 @@ th[role=columnheader]:not(.no-sort):hover:after {
|
|
|
847
910
|
/* dataset search result highlighting */
|
|
848
911
|
.tpDatasetLabel mark { background: #fff176; color: inherit; padding: 0 1px; border-radius: 2px; }
|
|
849
912
|
.list-group-item.active .tpDatasetLabel mark { background: #ffe57f; }
|
|
913
|
+
|
|
914
|
+
/* ============================================================
|
|
915
|
+
Differential Expression feature (Redmine #24912)
|
|
916
|
+
New surfaces only. A/B group colors are load-bearing (do not
|
|
917
|
+
swap without preserving warm-vs-cool contrast). Accent maps to
|
|
918
|
+
the Cell Browser primary (#337ab7).
|
|
919
|
+
============================================================ */
|
|
920
|
+
:root {
|
|
921
|
+
--tpDeAccent: #337ab7;
|
|
922
|
+
--tpDeA: #c2603a; --tpDeAtint: #fbf1ec; --tpDeAborder: #eccdbe; --tpDeAtext: #a94c2c; --tpDeAmuted: #9a7f70;
|
|
923
|
+
--tpDeB: #42559f; --tpDeBtint: #eef0f9; --tpDeBborder: #c6cce8; --tpDeBtext: #3a4a8c; --tpDeBmuted: #77809f;
|
|
924
|
+
--tpDeCard: #fff; --tpDeCardBorder: #e2e0da; --tpDeInk: #23262b; --tpDeMuted: #6b6f76; --tpDeTert: #8b8f96;
|
|
925
|
+
--tpDeTrack: #eceae4; --tpDeHair: #e7e5df;
|
|
926
|
+
}
|
|
927
|
+
/* builder lives inside the sidebar Tools tab; flows normally, plain white bg
|
|
928
|
+
and the default UI font, so it matches the rest of the sidebar */
|
|
929
|
+
#tpDeBuilder { background:#fff; font-size:13px; color:var(--tpDeInk);
|
|
930
|
+
font-family:Arial,Helvetica,sans-serif; }
|
|
931
|
+
#tpDeBuilder .tpDeHead { padding:11px 4px 11px; border-bottom:1px solid var(--tpDeHair); position:relative; }
|
|
932
|
+
#tpDeBuilder .tpDeTitle { font-size:15px; font-weight:600; letter-spacing:-0.01em; }
|
|
933
|
+
#tpDeBuilder .tpDeSub { font-size:13px; color:var(--tpDeTert); margin-top:2px; }
|
|
934
|
+
#tpDeBuilder .tpDeClose { position:absolute; right:2px; top:9px; font-size:18px; color:var(--tpDeTert);
|
|
935
|
+
cursor:pointer; line-height:1; padding:2px 5px; border-radius:4px; }
|
|
936
|
+
#tpDeBuilder .tpDeClose:hover { color:var(--tpDeInk); background:#ece9e2; }
|
|
937
|
+
/* the body scrolls when the group lists get long (e.g. after 'swap' materializes
|
|
938
|
+
all-other-cells), mirroring #tpMetaPanel on the Annotation tab */
|
|
939
|
+
#tpDeBuilder .tpDeBody { padding:12px 2px 16px; display:flex; flex-direction:column; gap:10px;
|
|
940
|
+
max-height:calc(100vh - 165px); overflow-y:auto; overflow-x:hidden; }
|
|
941
|
+
|
|
942
|
+
/* which group legend clicks are assigned to */
|
|
943
|
+
.tpDeTargetRow { display:flex; align-items:center; gap:8px; }
|
|
944
|
+
.tpDeTargetRow .tpDeTargetLabel { font-size:13px; color:var(--tpDeMuted); white-space:nowrap; }
|
|
945
|
+
/* "Compare by" field selector at the top of the builder */
|
|
946
|
+
.tpDeFieldRow { display:flex; align-items:center; gap:8px; margin-bottom:2px; }
|
|
947
|
+
.tpDeFieldRow .tpDeFieldLabel { font-size:13px; color:var(--tpDeMuted); white-space:nowrap; }
|
|
948
|
+
.tpDeFieldRow .tpDeField { flex:1 1 0; min-width:0; font-size:13px; padding:4px 5px;
|
|
949
|
+
border:1px solid var(--tpDeCardBorder); border-radius:5px; background:#fff; }
|
|
950
|
+
/* in-builder clickable value list (assign to A/B without the far-right legend) */
|
|
951
|
+
.tpDeValHead { display:flex; align-items:baseline; justify-content:space-between; gap:6px; margin-top:8px; }
|
|
952
|
+
.tpDeValTo { font-size:12px; font-weight:600; letter-spacing:0.02em; }
|
|
953
|
+
.tpDeValTot { font-size:12px; font-family:monospace; color:var(--tpDeTert); }
|
|
954
|
+
.tpDeValFilter { width:100%; box-sizing:border-box; font-size:13px; padding:5px 8px; margin-top:4px;
|
|
955
|
+
border:1px solid var(--tpDeCardBorder); border-radius:5px; }
|
|
956
|
+
/* flex:none stops the builder's flex column from shrinking this to 1-2 rows on a
|
|
957
|
+
short window; it holds its height (up to 40vh) and the builder scrolls instead */
|
|
958
|
+
.tpDeValList { flex:none; max-height:305px; min-height:150px; overflow-y:auto; margin-top:5px;
|
|
959
|
+
background:#fff; border:1px solid var(--tpDeCardBorder); border-radius:5px; }
|
|
960
|
+
.tpDeValRow { display:flex; align-items:center; gap:8px; padding:6px 10px; cursor:pointer;
|
|
961
|
+
font-size:13px; border-bottom:1px solid #f1eee7; }
|
|
962
|
+
.tpDeValRow:last-child { border-bottom:none; }
|
|
963
|
+
.tpDeValRow:hover { background:#f0ece4; }
|
|
964
|
+
.tpDeValRow.tpDeValOn:hover { filter:brightness(0.97); }
|
|
965
|
+
.tpDeValDot { width:11px; height:11px; border-radius:50%; flex:none; }
|
|
966
|
+
.tpDeValLbl { flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
|
967
|
+
.tpDeValN { font-size:11px; font-family:monospace; color:var(--tpDeMuted); }
|
|
968
|
+
.tpDeValBadge { flex:none; width:16px; height:16px; line-height:16px; text-align:center;
|
|
969
|
+
font-size:11px; font-weight:600; color:#fff; border-radius:3px; }
|
|
970
|
+
.tpDeValBadge.tpDeValBadgeEmpty { background:transparent; }
|
|
971
|
+
.tpDeValEmpty { padding:10px; font-size:12px; color:var(--tpDeTert); text-align:center; }
|
|
972
|
+
.tpDeCard.tpDeActive { border-color:var(--tpDeAccent); box-shadow:0 0 0 1px var(--tpDeAccent); }
|
|
973
|
+
|
|
974
|
+
.tpDeCard { background:var(--tpDeCard); border:1px solid var(--tpDeCardBorder); border-radius:7px; padding:11px 11px 12px; }
|
|
975
|
+
.tpDeCardHead { display:flex; align-items:center; gap:7px; margin-bottom:9px; }
|
|
976
|
+
.tpDeDot { width:9px; height:9px; border-radius:50%; flex:none; }
|
|
977
|
+
.tpDeCardLabel { font-size:13px; font-weight:600; letter-spacing:0.02em; }
|
|
978
|
+
.tpDeCount { margin-left:auto; font-size:13px; font-family:monospace; color:var(--tpDeMuted); }
|
|
979
|
+
.tpDeCount.tpDeWarn { color:#b4522c; }
|
|
980
|
+
.tpDeHint { font-size:13px; color:var(--tpDeMuted); line-height:1.5; padding:6px 8px; border:1px dashed var(--tpDeCardBorder); border-radius:5px; }
|
|
981
|
+
.tpDeChips { display:flex; flex-wrap:wrap; gap:5px; }
|
|
982
|
+
.tpDeChip { display:inline-flex; align-items:center; gap:6px; border-radius:20px; padding:3px 4px 3px 8px; font-size:13px; border:1px solid; }
|
|
983
|
+
.tpDeChip .tpDeChipDot { width:7px; height:7px; border-radius:50%; flex:none; }
|
|
984
|
+
.tpDeChip .tpDeChipN { font-size:12px; font-family:monospace; }
|
|
985
|
+
.tpDeChip .tpDeChipX { cursor:pointer; font-size:13px; padding:0 2px; border-radius:50%; }
|
|
986
|
+
.tpDeFilterRow { display:flex; gap:6px; margin-top:9px; }
|
|
987
|
+
/* min-width:0 lets the selects shrink instead of spilling past the sidebar when
|
|
988
|
+
an option label is long (e.g. "subset clusters") */
|
|
989
|
+
.tpDeFilterRow select { flex:1 1 0; min-width:0; max-width:100%; font-size:13px; padding:4px 5px; border:1px solid var(--tpDeCardBorder); border-radius:5px; background:#fff; }
|
|
990
|
+
/* selected filter values (multi-value) shown as removable chips */
|
|
991
|
+
.tpDeFilterChips { display:flex; flex-wrap:wrap; gap:4px; margin-top:5px; }
|
|
992
|
+
.tpDeFilterChip { display:inline-flex; align-items:center; gap:5px; font-size:12px; background:#efece5;
|
|
993
|
+
border:1px solid var(--tpDeCardBorder); border-radius:12px; padding:2px 4px 2px 8px; }
|
|
994
|
+
.tpDeFilterChip .tpDeFilterChipX { cursor:pointer; font-size:13px; line-height:1; padding:0 3px; border-radius:50%; color:var(--tpDeTert); }
|
|
995
|
+
.tpDeFilterChip .tpDeFilterChipX:hover { color:var(--tpDeInk); background:#ddd8cf; }
|
|
996
|
+
|
|
997
|
+
.tpDeSwap { display:flex; align-items:center; gap:8px; }
|
|
998
|
+
.tpDeSwap .tpDeSwapLine { flex:1; height:1px; background:var(--tpDeHair); }
|
|
999
|
+
.tpDeSwapBtn { font-size:12px; color:var(--tpDeTert); border:1px solid var(--tpDeCardBorder); background:#fff;
|
|
1000
|
+
border-radius:20px; padding:3px 10px; cursor:pointer; }
|
|
1001
|
+
.tpDeSwapBtn:hover { border-color:var(--tpDeAccent); color:var(--tpDeAccent); }
|
|
1002
|
+
|
|
1003
|
+
.tpDeSeg { display:flex; background:#efece5; border-radius:5px; padding:2px; margin-bottom:9px; }
|
|
1004
|
+
.tpDeSeg button { flex:1; padding:5px 0; font-size:13px; border:none; background:none; border-radius:4px; cursor:pointer; color:var(--tpDeMuted); }
|
|
1005
|
+
.tpDeSeg button.tpDeSegOn { background:#fff; font-weight:600; color:var(--tpDeInk); box-shadow:0 1px 2px rgba(0,0,0,0.07); }
|
|
1006
|
+
.tpDeRestNote { font-size:13px; color:var(--tpDeTert); line-height:1.5; }
|
|
1007
|
+
|
|
1008
|
+
.tpDeSettings .tpDeSettingsHead { display:flex; align-items:center; padding:4px 11px; cursor:pointer; }
|
|
1009
|
+
.tpDeSettings .tpDeSettingsHead b { font-size:13px; font-weight:600; }
|
|
1010
|
+
.tpDeSettings .tpDeSummary { margin-left:auto; font-size:12px; font-family:monospace; color:var(--tpDeMuted); }
|
|
1011
|
+
.tpDeSettingsBody { padding:1px 11px 6px; border-top:1px solid var(--tpDeHair); }
|
|
1012
|
+
.tpDeSetRow { display:flex; align-items:center; gap:9px; margin-top:4px; }
|
|
1013
|
+
.tpDeSetRow label { flex:1 1 auto; min-width:0; font-size:13px; }
|
|
1014
|
+
.tpDeSetRow select, .tpDeSetRow input { flex:0 1 150px; min-width:0; max-width:150px; font-size:13px; padding:3px 5px; border:1px solid var(--tpDeCardBorder); border-radius:4px; }
|
|
1015
|
+
.tpDeFoot { font-size:11px; color:var(--tpDeMuted); margin-top:5px; }
|
|
1016
|
+
|
|
1017
|
+
.tpDeBanner { background:#fdf3ed; border:1px solid #efd0bc; border-radius:6px; padding:9px 11px; font-size:13px; color:#8a4a26; line-height:1.5; }
|
|
1018
|
+
.tpDeRunRow { display:flex; gap:8px; }
|
|
1019
|
+
.tpDeRun { flex:1; padding:9px 12px; border-radius:6px; font-size:14px; font-weight:600; color:#fff; background:var(--tpDeAccent); border:none; cursor:pointer; }
|
|
1020
|
+
.tpDeRun:disabled { background:#cfccc5; color:#8b8f96; cursor:default; }
|
|
1021
|
+
.tpDeReset { padding:9px 12px; border:1px solid var(--tpDeCardBorder); background:#fff; border-radius:6px; cursor:pointer; font-size:14px; }
|
|
1022
|
+
|
|
1023
|
+
.tpDeRecentLabel { font-size:12px; font-weight:600; text-transform:uppercase; letter-spacing:0.06em; color:var(--tpDeTert); margin-top:6px; }
|
|
1024
|
+
.tpDeRecent { padding:7px 9px; border:1px solid var(--tpDeCardBorder); border-radius:5px; background:#fff; margin-bottom:5px; cursor:pointer; }
|
|
1025
|
+
.tpDeRecent:hover { border-color:var(--tpDeAccent); }
|
|
1026
|
+
.tpDeRecent .tpDeRecentTitle { font-size:13px; line-height:1.4; }
|
|
1027
|
+
.tpDeRecent .tpDeRecentSub { font-size:12px; font-family:monospace; color:var(--tpDeMuted); }
|
|
1028
|
+
|
|
1029
|
+
/* collapsible comparison-list sections (Saved / Recent) */
|
|
1030
|
+
.tpDeListSec { margin-top:6px; }
|
|
1031
|
+
.tpDeListHead { font-size:12px; font-weight:600; text-transform:uppercase; letter-spacing:0.06em;
|
|
1032
|
+
color:var(--tpDeTert); cursor:pointer; user-select:none; padding:2px 0; }
|
|
1033
|
+
.tpDeListHead:hover { color:var(--tpDeInk); }
|
|
1034
|
+
.tpDeListCaret { display:inline-block; width:12px; color:var(--tpDeMuted); }
|
|
1035
|
+
.tpDeListBody { margin-top:4px; }
|
|
1036
|
+
|
|
1037
|
+
/* saved comparisons: like a recent row, plus Share / delete controls */
|
|
1038
|
+
.tpDeSaved { display:flex; align-items:center; gap:6px; padding:7px 9px; border:1px solid var(--tpDeCardBorder);
|
|
1039
|
+
border-radius:5px; background:#fff; margin-bottom:5px; }
|
|
1040
|
+
.tpDeSaved:hover { border-color:var(--tpDeAccent); }
|
|
1041
|
+
.tpDeSaved .tpDeSavedMain { flex:1 1 auto; min-width:0; cursor:pointer; }
|
|
1042
|
+
.tpDeSaved .tpDeRecentTitle { font-size:13px; line-height:1.4; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
|
1043
|
+
.tpDeSaved .tpDeRecentSub { font-size:12px; font-family:monospace; color:var(--tpDeMuted); }
|
|
1044
|
+
.tpDeSavedAct { flex:none; cursor:pointer; color:var(--tpDeTert); border-radius:4px; padding:1px 5px; user-select:none; }
|
|
1045
|
+
.tpDeSavedShare { font-size:12px; }
|
|
1046
|
+
.tpDeSavedDel { font-size:15px; line-height:1; }
|
|
1047
|
+
.tpDeSavedAct:hover { color:var(--tpDeAccent); background:#ece9e2; }
|
|
1048
|
+
|
|
1049
|
+
/* "Save to account" shown greyed when signed out (still clickable -> opens sign-in) */
|
|
1050
|
+
.ui-dialog-buttonpane button.tpDeBtnDisabled { opacity:0.5; }
|
|
1051
|
+
.ui-dialog-buttonpane button.tpDeBtnDisabled:hover { opacity:0.65; }
|
|
1052
|
+
|
|
1053
|
+
/* transient confirmation toast (e.g. after saving a comparison) */
|
|
1054
|
+
.tpDeToast { position:fixed; left:50%; bottom:40px; transform:translateX(-50%); z-index:100000;
|
|
1055
|
+
background:rgba(35,38,43,0.92); color:#fff; font-size:13px; padding:8px 16px; border-radius:5px;
|
|
1056
|
+
box-shadow:0 2px 10px rgba(0,0,0,0.25); pointer-events:none; }
|
|
1057
|
+
|
|
1058
|
+
/* legend A/B buttons (added while builder open) */
|
|
1059
|
+
.tpDeLegBtns { display:inline-flex; gap:3px; margin-left:6px; vertical-align:middle; }
|
|
1060
|
+
.tpDeLegBtn { width:19px; height:19px; border-radius:4px; font-size:11px; font-weight:600; line-height:17px;
|
|
1061
|
+
text-align:center; border:1px solid #d6d3cc; background:#fff; color:#b7b4ad; cursor:pointer; padding:0; }
|
|
1062
|
+
.tpDeLegBtn.tpDeLegA.tpDeOn { background:var(--tpDeA); border-color:var(--tpDeA); color:#fff; }
|
|
1063
|
+
.tpDeLegBtn.tpDeLegB.tpDeOn { background:var(--tpDeB); border-color:var(--tpDeB); color:#fff; }
|
|
1064
|
+
.tpLegend.tpDeRowA { background:var(--tpDeAtint); border-color:var(--tpDeAborder) !important; }
|
|
1065
|
+
.tpLegend.tpDeRowB { background:var(--tpDeBtint); border-color:var(--tpDeBborder) !important; }
|
|
1066
|
+
|
|
1067
|
+
/* running overlay confined to the plot area */
|
|
1068
|
+
#tpDeRunning { position:absolute; z-index:20; background:rgba(255,255,255,0.72);
|
|
1069
|
+
display:flex; align-items:center; justify-content:center; }
|
|
1070
|
+
#tpDeRunning .tpDeRunCard { width:330px; background:#fff; border:1px solid var(--tpDeCardBorder); border-radius:9px;
|
|
1071
|
+
box-shadow:0 16px 42px rgba(10,12,15,0.16); padding:20px 24px; }
|
|
1072
|
+
#tpDeRunning .tpDeRunTop { display:flex; align-items:center; gap:10px; font-size:14px; font-weight:600; }
|
|
1073
|
+
#tpDeSpinner { width:15px; height:15px; border:2px solid #dcdad3; border-top-color:var(--tpDeAccent);
|
|
1074
|
+
border-radius:50%; animation:tpDeSpin .8s linear infinite; flex:none; }
|
|
1075
|
+
@keyframes tpDeSpin { to { transform:rotate(360deg); } }
|
|
1076
|
+
#tpDeRunning .tpDeProgTrack { height:5px; background:var(--tpDeTrack); border-radius:3px; margin-top:14px; overflow:hidden; }
|
|
1077
|
+
#tpDeRunning .tpDeProgFill { height:100%; width:0; background:var(--tpDeAccent); border-radius:3px; transition:width .3s ease; }
|
|
1078
|
+
#tpDeRunning .tpDeStage { margin-top:9px; font-size:13px; font-family:monospace; color:var(--tpDeTert); }
|
|
1079
|
+
#tpDeRunning .tpDeCancel { margin-top:12px; text-align:right; }
|
|
1080
|
+
#tpDeRunning .tpDeCancel button { font-size:12px; border:1px solid var(--tpDeCardBorder); background:#fff; border-radius:5px; padding:4px 10px; cursor:pointer; }
|
|
1081
|
+
|
|
1082
|
+
/* results pop-up (non-modal dialog) */
|
|
1083
|
+
#tpDeResults { font-size:13px; color:var(--tpDeInk); font-family:Arial,Helvetica,sans-serif; }
|
|
1084
|
+
/* jQuery UI forces Verdana on .ui-widget content; keep the DE dialog on the
|
|
1085
|
+
default UI font (its title bar is part of the widget chrome) */
|
|
1086
|
+
.ui-dialog:has(#tpDeResults), .ui-dialog:has(#tpDeResults) .ui-dialog-title { font-family:Arial,Helvetica,sans-serif; }
|
|
1087
|
+
#tpDeResults .tpDeResHead { display:flex; align-items:baseline; gap:12px; padding:6px 2px 10px; border-bottom:1px solid var(--tpDeHair); }
|
|
1088
|
+
#tpDeResults .tpDeResTitle { font-size:14px; font-weight:600; letter-spacing:-0.01em; }
|
|
1089
|
+
#tpDeResults .tpDeResSub { font-size:13px; font-family:monospace; color:var(--tpDeMuted); }
|
|
1090
|
+
#tpDeResBody { display:flex; height:100%; }
|
|
1091
|
+
#tpDeResTableWrap { flex:1; display:flex; flex-direction:column; border-right:1px solid var(--tpDeHair); min-width:0; overflow-y:auto; }
|
|
1092
|
+
#tpDeResVolcano { width:360px; flex:none; padding:8px 12px 10px; overflow-y:auto; }
|
|
1093
|
+
.tpDeCtrls { display:flex; align-items:center; gap:8px; padding:8px 4px 6px; }
|
|
1094
|
+
.tpDeCtrls input.tpDeGeneFilter { width:150px; font-size:13px; padding:4px 8px; border:1px solid var(--tpDeCardBorder); border-radius:4px; }
|
|
1095
|
+
.tpDeCtrls2 { padding:0 4px 8px; border-bottom:1px solid var(--tpDeHair); }
|
|
1096
|
+
.tpDeGeneCount { margin-left:auto; font-size:12px; font-family:monospace; color:var(--tpDeTert); }
|
|
1097
|
+
/* results table: Bootstrap .table look, matching the cluster-markers pop-up */
|
|
1098
|
+
#tpDeTable { margin-bottom:0; }
|
|
1099
|
+
#tpDeTable thead th { position:sticky; top:0; background:#fff; cursor:pointer; white-space:nowrap;
|
|
1100
|
+
border-bottom:2px solid #ddd; }
|
|
1101
|
+
#tpDeTable thead th.tpDeSortOn { color:var(--tpDeAccent); }
|
|
1102
|
+
#tpDeTable td, #tpDeTable th { font-size:13px; padding:5px 7px; white-space:nowrap; }
|
|
1103
|
+
#tpDeTable td.tpDeNum, #tpDeTable th.tpDeNum { text-align:right; }
|
|
1104
|
+
#tpDeTable tbody tr { cursor:pointer; }
|
|
1105
|
+
#tpDeTable tbody tr:hover { background:#f5f5f5; }
|
|
1106
|
+
#tpDeTable tbody tr.tpDeRowSel > td { background:#eaf1f8; }
|
|
1107
|
+
.tpDeGene { font-family:monospace; font-weight:500; white-space:nowrap; max-width:120px; overflow:hidden; text-overflow:ellipsis; }
|
|
1108
|
+
.tpDeGene .tpDeDirDot { display:inline-block; width:6px; height:6px; border-radius:50%; margin-right:6px; vertical-align:middle; }
|
|
1109
|
+
.tpDeNum { font-family:monospace; }
|
|
1110
|
+
#tpDeResVolcano .tpDeVolHead { display:flex; align-items:baseline; }
|
|
1111
|
+
#tpDeResVolcano .tpDeVolTitle { font-size:12px; font-weight:600; letter-spacing:0.04em; text-transform:uppercase; color:var(--tpDeMuted); }
|
|
1112
|
+
#tpDeResVolcano .tpDeVolHint { margin-left:auto; font-size:12px; color:var(--tpDeTert); }
|
|
1113
|
+
.tpDeEmpty { display:flex; flex-direction:column; align-items:center; justify-content:center; gap:9px; height:100%; padding:0 40px; text-align:center; }
|
|
1114
|
+
.tpDeEmpty h3 { font-size:15px; font-weight:600; margin:0; }
|
|
1115
|
+
.tpDeEmpty p { font-size:14px; color:var(--tpDeTert); line-height:1.6; max-width:520px; }
|
|
1116
|
+
.tpDeEmptyBtns { display:flex; gap:8px; margin-top:5px; }
|
|
1117
|
+
.tpDeEmptyBtns .tpDeLoosen { background:var(--tpDeAccent); color:#fff; border:none; padding:7px 13px; font-size:13px; border-radius:5px; cursor:pointer; }
|
|
1118
|
+
.tpDeEmptyBtns .tpDeEditGroups { background:#fff; border:1px solid var(--tpDeCardBorder); padding:7px 13px; font-size:13px; border-radius:5px; cursor:pointer; }
|
|
1119
|
+
|
|
1120
|
+
/* Debug timing bar (?debug=1): fixed strip along the bottom of the window that
|
|
1121
|
+
shows the ms spent in each dataset-load phase. Only created when debug mode is
|
|
1122
|
+
on; see cbTiming() in cellBrowser.js. Dark, monospace, out of the way. */
|
|
1123
|
+
#tpDebugBar {
|
|
1124
|
+
position: fixed; left: 0; right: 0; bottom: 0;
|
|
1125
|
+
background: rgba(24,24,24,0.90); color: #d8d8d8;
|
|
1126
|
+
font-family: Menlo, Consolas, monospace; font-size: 13px;
|
|
1127
|
+
padding: 0 14px;
|
|
1128
|
+
border-top: 1px solid #444; z-index: 100000;
|
|
1129
|
+
}
|
|
1130
|
+
/* one row per timing run: the dataset load, then a DE job. Each scrolls on its
|
|
1131
|
+
own, and the right padding keeps a long row from running under the close box. */
|
|
1132
|
+
#tpDebugBar .tpDebugRow {
|
|
1133
|
+
height: 32px; line-height: 32px; white-space: nowrap; overflow-x: auto;
|
|
1134
|
+
padding-right: 26px;
|
|
1135
|
+
}
|
|
1136
|
+
#tpDebugBar .tpDebugRow + .tpDebugRow { border-top: 1px solid #3a3a3a; }
|
|
1137
|
+
#tpDebugBar .tpDebugSeg { margin-right: 20px; }
|
|
1138
|
+
#tpDebugBar .tpDebugTag { color: #7fb0ff; font-weight: bold; text-transform: uppercase; letter-spacing: 0.5px; }
|
|
1139
|
+
#tpDebugBar .tpDebugLbl { color: #9fd0ff; }
|
|
1140
|
+
#tpDebugBar .tpDebugVal { color: #ffd48a; }
|
|
1141
|
+
#tpDebugBar .tpDebugTot { color: #9fe6a0; }
|
|
1142
|
+
#tpDebugBar .tpDebugGroup { color: #7fb0ff; font-weight: bold; text-transform: uppercase; letter-spacing: 0.5px; }
|
|
1143
|
+
#tpDebugBar .tpDebugDraw { color: #f0a0ff; }
|
|
1144
|
+
#tpDebugBar .tpDebugClose {
|
|
1145
|
+
position: absolute; right: 12px; top: 0; height: 32px; line-height: 32px;
|
|
1146
|
+
cursor: pointer; color: #aaa; font-weight: bold;
|
|
1147
|
+
}
|
|
1148
|
+
#tpDebugBar .tpDebugClose:hover { color: #fff; }
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Build the mouse gene symbol -> MGI ID table that the marker table uses to link
|
|
2
|
+
# straight to a gene page instead of to a search hit list.
|
|
3
|
+
#
|
|
4
|
+
# Input is the MGI file we already ship for ortholog mapping, cellbrowserData/geneAnnot/
|
|
5
|
+
# mgi_HGNC_homologene_8Dec17.txt, which carries the accession, the symbol and the feature
|
|
6
|
+
# type. Nothing new has to be downloaded.
|
|
7
|
+
#
|
|
8
|
+
# Only protein coding genes are kept. That is 23k of the 70k markers in the file and covers
|
|
9
|
+
# 93% of the symbols in the marker tables we serve, where taking everything would cover 96%
|
|
10
|
+
# for nearly three times the transfer. A symbol that is not in the table falls back to the
|
|
11
|
+
# symbol search, so the genes left out still get a working link.
|
|
12
|
+
#
|
|
13
|
+
# Output is JSON rather than TSV because the server gzips application/json and does not gzip
|
|
14
|
+
# text/tab-separated-values, so the JSON is the smaller of the two over the wire. The "MGI:"
|
|
15
|
+
# prefix is dropped and put back by the browser.
|
|
16
|
+
#
|
|
17
|
+
# python3 makeMgiIds.py ../../../../../cellbrowserData/geneAnnot/mgi_HGNC_homologene_8Dec17.txt
|
|
18
|
+
#
|
|
19
|
+
# Name the output after the version of the input, so it can be cached forever.
|
|
20
|
+
|
|
21
|
+
import json, sys, gzip
|
|
22
|
+
from os.path import basename
|
|
23
|
+
|
|
24
|
+
def main():
|
|
25
|
+
if len(sys.argv) < 2:
|
|
26
|
+
sys.exit("usage: makeMgiIds.py <mgi_HGNC_homologene file> [outFname]")
|
|
27
|
+
inFname = sys.argv[1]
|
|
28
|
+
|
|
29
|
+
if len(sys.argv) > 2:
|
|
30
|
+
outFname = sys.argv[2]
|
|
31
|
+
else:
|
|
32
|
+
# mgi_HGNC_homologene_8Dec17.txt -> mgiIds-8Dec17.json
|
|
33
|
+
stem = basename(inFname).rsplit(".", 1)[0]
|
|
34
|
+
outFname = "mgiIds-%s.json" % stem.split("_")[-1]
|
|
35
|
+
|
|
36
|
+
symToId = {}
|
|
37
|
+
skipped = 0
|
|
38
|
+
for i, line in enumerate(open(inFname, encoding="utf8", errors="replace")):
|
|
39
|
+
if i == 0:
|
|
40
|
+
continue
|
|
41
|
+
row = line.rstrip("\n").split("\t")
|
|
42
|
+
if len(row) < 4:
|
|
43
|
+
continue
|
|
44
|
+
mgiId, sym, _, featType = row[0], row[1], row[2], row[3]
|
|
45
|
+
if not sym or not mgiId.startswith("MGI:"):
|
|
46
|
+
continue
|
|
47
|
+
if featType != "protein coding gene":
|
|
48
|
+
skipped += 1
|
|
49
|
+
continue
|
|
50
|
+
symToId[sym] = int(mgiId[4:])
|
|
51
|
+
|
|
52
|
+
blob = json.dumps(symToId, separators=(",", ":"), sort_keys=True)
|
|
53
|
+
with open(outFname, "w") as ofh:
|
|
54
|
+
ofh.write(blob)
|
|
55
|
+
|
|
56
|
+
gzSize = len(gzip.compress(blob.encode(), 9))
|
|
57
|
+
print("%s: %d protein coding symbols (%d other features skipped)" % (outFname, len(symToId), skipped))
|
|
58
|
+
print(" %.1f KB, %.1f KB gzipped as the server will send it" % (len(blob)/1024.0, gzSize/1024.0))
|
|
59
|
+
|
|
60
|
+
main()
|