cellbrowser 1.2.14__tar.gz → 1.2.15.post0.dev8__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.
Files changed (180) hide show
  1. {cellbrowser-1.2.14/src/cbPyLib/cellbrowser.egg-info → cellbrowser-1.2.15.post0.dev8}/PKG-INFO +2 -11
  2. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/R/cellbrowser.R +17 -2
  3. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/_version.py +3 -3
  4. cellbrowser-1.2.15.post0.dev8/src/cbPyLib/cellbrowser/bw_genes.py +624 -0
  5. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/css/cellBrowser.css +11 -1
  6. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/js/cellBrowser.js +45 -22
  7. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/js/maxPlot.js +62 -4
  8. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cellbrowser.py +26 -18
  9. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/seurat.py +13 -9
  10. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8/src/cbPyLib/cellbrowser.egg-info}/PKG-INFO +2 -11
  11. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser.egg-info/SOURCES.txt +1 -0
  12. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/LICENSE +0 -0
  13. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/MANIFEST.in +0 -0
  14. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/README.rst +0 -0
  15. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/setup.cfg +0 -0
  16. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/setup.py +0 -0
  17. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/RangeHTTPServer/__init__.py +0 -0
  18. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/RangeHTTPServer/__main__.py +0 -0
  19. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/__init__.py +0 -0
  20. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/css/MaterialIcons-Regular.eot +0 -0
  21. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/css/MaterialIcons-Regular.ttf +0 -0
  22. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/css/MaterialIcons-Regular.woff +0 -0
  23. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/css/MaterialIcons-Regular.woff2 +0 -0
  24. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/Chart.bundle.min.js +0 -0
  25. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/FastBitSet.js +0 -0
  26. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/FileSaver.1.1.20151003.min.js +0 -0
  27. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/OverlayScrollbars.min.css +0 -0
  28. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/bootstrap-dropmenu.min.css +0 -0
  29. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/bootstrap-submenu.js +0 -0
  30. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/bootstrap-submenu.min.css +0 -0
  31. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/bootstrap.3.3.7.min.css +0 -0
  32. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/bootstrap.min.css +0 -0
  33. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/bootstrap.min.js +0 -0
  34. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/chartjs-chart-box-and-violin-plot.js +0 -0
  35. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/chosen-sprite.png +0 -0
  36. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/chosen-sprite@2x.png +0 -0
  37. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/chosen.1.8.2.min.css +0 -0
  38. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/chosen.jquery.min.js +0 -0
  39. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/drawImage-clipper.js +0 -0
  40. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/font-awesome.css +0 -0
  41. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/googleMaterialIcons.css +0 -0
  42. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/hamster.js +0 -0
  43. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  44. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/images/ui-icons_444444_256x240.png +0 -0
  45. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/images/ui-icons_555555_256x240.png +0 -0
  46. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/images/ui-icons_777620_256x240.png +0 -0
  47. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/images/ui-icons_777777_256x240.png +0 -0
  48. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/images/ui-icons_cc0000_256x240.png +0 -0
  49. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/images/ui-icons_ffffff_256x240.png +0 -0
  50. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/intro.min.js +0 -0
  51. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/introjs.2.4.0.min.css +0 -0
  52. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/jquery-ui-1.12.1.css +0 -0
  53. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/jquery-ui.min.js +0 -0
  54. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/jquery.3.1.1.min.js +0 -0
  55. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/jquery.contextMenu.css +0 -0
  56. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/jquery.contextMenu.js +0 -0
  57. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/jquery.event.drag-2.3.0.js +0 -0
  58. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/jquery.overlayScrollbars.min.js +0 -0
  59. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/jquery.sparkline.min.js +0 -0
  60. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/jquery.tablesorter.js +0 -0
  61. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/jquery.tablesorter.widgets.js +0 -0
  62. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/jquery.tipsy.1.0.3.min.css +0 -0
  63. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/jquery.tipsy.min.js +0 -0
  64. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/jquery.ui.position.min.js +0 -0
  65. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/jsurl2.js +0 -0
  66. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/lz-string.js +0 -0
  67. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/materialIcons.woff +0 -0
  68. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/minified.js +0 -0
  69. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/mousetrap.min.js +0 -0
  70. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/normalizeWheel.js +0 -0
  71. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/pako_inflate.min.js +0 -0
  72. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/palette.js +0 -0
  73. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/papaparse.min.js +0 -0
  74. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/reorder.v1.js +0 -0
  75. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/scaleColorPerceptual.js +0 -0
  76. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/science.v1.js +0 -0
  77. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/select2.4.0.4.min.css +0 -0
  78. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/select2.min.js +0 -0
  79. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/selectize.bootstrap3.css +0 -0
  80. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/selectize.js +0 -0
  81. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/slick.cellrangedecorator.js +0 -0
  82. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/slick.cellrangeselector.js +0 -0
  83. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/slick.cellselectionmodel.js +0 -0
  84. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/slick.core.js +0 -0
  85. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/slick.editors.js +0 -0
  86. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/slick.examples.css +0 -0
  87. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/slick.formatters.js +0 -0
  88. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/slick.grid.css +0 -0
  89. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/slick.grid.js +0 -0
  90. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/spectrum-1.8.0.css +0 -0
  91. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/spectrum.min.js +0 -0
  92. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/split.js +0 -0
  93. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/tablesort.js +0 -0
  94. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/tablesort.number.min.js +0 -0
  95. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/.npmignore +0 -0
  96. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/LICENSE +0 -0
  97. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/Makefile +0 -0
  98. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/README.md +0 -0
  99. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/browser.js +0 -0
  100. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/build.js +0 -0
  101. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/example/d3-random-matrix.js +0 -0
  102. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/example/example.png +0 -0
  103. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/example/gradients.js +0 -0
  104. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/example/package.json +0 -0
  105. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/hex/inferno.json +0 -0
  106. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/hex/magma.json +0 -0
  107. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/hex/plasma.json +0 -0
  108. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/hex/viridis.json +0 -0
  109. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/inferno.js +0 -0
  110. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/magma.js +0 -0
  111. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/package.json +0 -0
  112. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/plasma.js +0 -0
  113. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/rgb/inferno.json +0 -0
  114. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/rgb/magma.json +0 -0
  115. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/rgb/plasma.json +0 -0
  116. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/rgb/viridis.json +0 -0
  117. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/utils/hex2rgb.js +0 -0
  118. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/utils/interpolate.js +0 -0
  119. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/utils/rgb2hex.js +0 -0
  120. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/temp/node_modules/scale-color-perceptual/viridis.js +0 -0
  121. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/theme.bootstrap_3.css +0 -0
  122. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/ext/tiny-queue.js +0 -0
  123. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/genes/files.json +0 -0
  124. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/genes/hg19.gc34.tsv +0 -0
  125. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/genes/hg19.json.gz +0 -0
  126. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/genes/hg38.gc34.tsv +0 -0
  127. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/genes/hg38.json.gz +0 -0
  128. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/genes/log.txt +0 -0
  129. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/genes/makeGenes.py +0 -0
  130. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/genes/mm10.json.gz +0 -0
  131. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/genes/mm10.vm25.tsv +0 -0
  132. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/README.md +0 -0
  133. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/center.png +0 -0
  134. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/README.txt +0 -0
  135. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/gtk-justify-left.png +0 -0
  136. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/gtk-save.png +0 -0
  137. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/log.txt +0 -0
  138. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-center-16.png +0 -0
  139. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-center-24.png +0 -0
  140. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-controller-16.png +0 -0
  141. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-controller-24.png +0 -0
  142. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-edit-16.png +0 -0
  143. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-gravity-west-24.png +0 -0
  144. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-info-16.png +0 -0
  145. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-info-24.png +0 -0
  146. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-merge-down-16.png +0 -0
  147. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-scale-16.png +0 -0
  148. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-tool-free-select-16.png +0 -0
  149. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-tool-free-select-22.png +0 -0
  150. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-tool-move-16.png +0 -0
  151. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-tool-move-22.png +0 -0
  152. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-tool-rect-select-16.png +0 -0
  153. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-tool-rect-select-22.png +0 -0
  154. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-tool-zoom-16.png +0 -0
  155. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/gimpFlat/stock-tool-zoom-22.png +0 -0
  156. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/icons8-help-32.png +0 -0
  157. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/info.png +0 -0
  158. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/lasso.png +0 -0
  159. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/marker.png +0 -0
  160. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/move.png +0 -0
  161. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/select.png +0 -0
  162. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/img/zoom.png +0 -0
  163. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/js/cbData.js +0 -0
  164. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/cbWeb/js/maxHeat.js +0 -0
  165. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/convert.py +0 -0
  166. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/download.py +0 -0
  167. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/geneinfo.py +0 -0
  168. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/genes.py +0 -0
  169. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/hubmaker.py +0 -0
  170. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/sampleConfig/cellbrowser.conf +0 -0
  171. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/sampleConfig/desc.conf +0 -0
  172. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/sampleConfig/hub.conf +0 -0
  173. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/sampleConfig/scanpy.conf +0 -0
  174. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/sampleConfig/seurat.conf +0 -0
  175. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser/sampleConfig/summary.html +0 -0
  176. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser.egg-info/dependency_links.txt +0 -0
  177. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser.egg-info/entry_points.txt +0 -0
  178. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser.egg-info/not-zip-safe +0 -0
  179. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/src/cbPyLib/cellbrowser.egg-info/top_level.txt +0 -0
  180. {cellbrowser-1.2.14 → cellbrowser-1.2.15.post0.dev8}/versioneer.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.1
2
2
  Name: cellbrowser
3
- Version: 1.2.14
3
+ Version: 1.2.15.post0.dev8
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
@@ -13,15 +13,6 @@ Classifier: Programming Language :: JavaScript
13
13
  Requires-Python: >=2.5
14
14
  Description-Content-Type: text/markdown
15
15
  License-File: LICENSE
16
- Dynamic: author
17
- Dynamic: author-email
18
- Dynamic: classifier
19
- Dynamic: description
20
- Dynamic: description-content-type
21
- Dynamic: home-page
22
- Dynamic: license
23
- Dynamic: requires-python
24
- Dynamic: summary
25
16
 
26
17
  The UCSC Cell Browser is an interactive browser for
27
18
  single cell data, like mRNA or ATAC-seq data. You can display
@@ -399,11 +399,26 @@ ExportToCellbrowser <- function(
399
399
  #res <- c(res[1:markers.n], rep(NA, naCount))
400
400
  #return(res)
401
401
  #}
402
- if (.hasSlot(object, "misc") && !is.null(x = object@misc["markers"][[1]])) {
402
+ hasMarkers = FALSE
403
+ if (.hasSlot(object, "misc") && !is.null(x = object@misc["markers"][[1]]) ) {
404
+ hasMarkers = TRUE
403
405
  message("Found precomputed markers in obj@misc['markers']")
404
- markers <- object@misc["markers"]$markers
406
+ }
407
+
408
+ if (skip.markers) {
409
+ message("Not using precomputed markers, as --skipMarkers was set")
410
+ hasMarkers = FALSE
411
+ }
412
+
413
+ if (hasMarkers) {
414
+ message("Using precomputed markers")
415
+ markers <- object@misc["markers"]$markers
405
416
  } else {
406
417
  message("Running FindAllMarkers(), using wilcox test, min logfc diff 0.25")
418
+ if ("SCT" %in% names(object@assays)) {
419
+ message("Looks like an SCT object, so running PrepSCTFindMarkers()")
420
+ PrepSCTFindMarkers(object = object)
421
+ }
407
422
  markers <- FindAllMarkers(
408
423
  object,
409
424
  do.print = TRUE,
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2025-04-18T11:54:57-0700",
11
+ "date": "2025-05-22T14:10:47-0700",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "578cc227d0f381f97e6f5b4cc649ed701103b066",
15
- "version": "1.2.14"
14
+ "full-revisionid": "ebe2e27cb09c7f85bdbfee91093a58c64c8ed1b9",
15
+ "version": "1.2.15.post0.dev8"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -0,0 +1,624 @@
1
+ # functions to guess the gene model release given a list of gene IDs
2
+ # tested on python3 and python2
3
+ import logging, sys, optparse, string, glob, gzip, json, subprocess
4
+ from io import StringIO
5
+
6
+ from collections import defaultdict
7
+ from os.path import join, basename, dirname, isfile
8
+
9
+ from .cellbrowser import sepForFile, getStaticFile, openFile, splitOnce, setDebug, getStaticPath
10
+ from .cellbrowser import getGeneSymPath, downloadUrlLines, getSymToGene, getGeneBedPath, errAbort, iterItems
11
+ from .cellbrowser import findCbData, readGeneSymbols, getGeneJsonPath, getDownloadsUrl
12
+
13
+ # ==== functions =====
14
+ def cbGenes_parseArgs():
15
+ " setup logging, parse command line arguments and options. -h shows auto-generated help page "
16
+ parser = optparse.OptionParser("""usage: %prog [options] command - download gene model files and auto-detect the version.
17
+
18
+ Commands for using gene models:
19
+ fetch <geneType> - download pre-built geneId -> symbol table from UCSC
20
+ fetch <assembly>.<geneType> - download pre-built gene models and symbol table from UCSC
21
+ guess <inFile> <organism> - Guess best gene type. Reads the first tab-sep field from inFile and prints genetypes sorted by % of matching unique IDs to inFile.
22
+ check <inFile> <geneType> - Check how well genes match given geneType
23
+
24
+ Commands for building new gene model files:
25
+ build <assembly>.<geneType> - Download a gene model file from UCSC, pick one transcript per gene and save to ~/cellbrowserData/genes/<db>.<geneType>.bed.gz and <geneType>.symbols.tsv.gz
26
+ allSyms [human|mouse] - Build one big table with geneId <-> symbol, valid for all Gencode versions, always use most recent symbol
27
+ add fname geneType - Add a two-column .tsv file to your local directory. First column is gene ID, second column is symbol.
28
+ e.g. 'cbGenes add myGenes.tsv sea-anemone'
29
+ index - Build the -unique index files and also run 'allSyms' for both human and mouse
30
+ push - Only at UCSC: copy all gene files to the export directory on hgwdev
31
+
32
+ Run "fetch" or "build" without arguments to list the available files at UCSC.
33
+
34
+ ls - list all available (built or downloaded) gene models on this machine
35
+
36
+ Examples (common):
37
+ %prog fetch # show the files that are available for the 'build' command
38
+ %prog fetch gencode-34 # geneId -> symbol mapping for human gencode relase 34
39
+ %prog fetch hg38.gencode-34 # gene -> chrom mapping for human gencode relase 34
40
+ %prog ls
41
+ %prog guess genes.txt mouse # guess the best gencode version for this file
42
+ %prog check features.tsv.gz gencode-40 # check if the genes match gencode-40 and which ones don't
43
+
44
+ Examples (rare - if you build your own gene models):
45
+ %prog build # show the files that are available
46
+ %prog build mm10 gencode-M25
47
+ %prog index # used at UCSC to prepare the files for 'guess'
48
+ %prog allSyms human # build big geneId -> symbol table from all
49
+ """)
50
+
51
+ parser.add_option("-d", "--debug", dest="debug", action="store_true", help="show debug messages")
52
+ (options, args) = parser.parse_args()
53
+
54
+ if args==[] or (args[0]=="guess" and len(args)==1):
55
+ parser.print_help()
56
+ exit(1)
57
+
58
+ setDebug(options.debug)
59
+ return args, options
60
+
61
+ # ----------- main --------------
62
+ def parseSignatures(org, geneIdType):
63
+ " return dict with gene release -> list of unique signature genes "
64
+ ret = {}
65
+ logging.info("Parsing gencode release signature genes")
66
+ fname = getStaticFile("genes/%s.%s.unique.tsv.gz" % (org, geneIdType))
67
+ logging.info("Parsing %s" % fname)
68
+ genes = set()
69
+ verToGenes = {}
70
+ for line in openFile(fname):
71
+ if line.startswith("#"):
72
+ continue
73
+ version, geneIds = line.rstrip("\n").split('\t')
74
+ geneIds = set(geneIds.split("|"))
75
+ verToGenes[version] = geneIds
76
+
77
+ return verToGenes
78
+
79
+ def guessGeneIdType(genes):
80
+ " return tuple organism / identifier type "
81
+ logging.debug("Trying to guess organism and identifier type (syms or ids)")
82
+ gene1 = list(genes)[0]
83
+ if gene1.startswith("ENSG"):
84
+ return "human", "ids"
85
+ if gene1.startswith("ENSMUS"):
86
+ return "mouse", "ids"
87
+
88
+ upCount = 0
89
+ for g in genes:
90
+ if g.isupper():
91
+ upCount += 1
92
+
93
+ logging.debug("%d of %d genes are uppercase" % (upCount, len(genes)))
94
+ if upCount/float(len(genes)) > 0.8:
95
+ return "human", "syms"
96
+ else:
97
+ return "mouse", "syms"
98
+
99
+ def parseGenes(fname):
100
+ " return gene IDs in column 1 of file "
101
+ fileGenes = set()
102
+ headDone = False
103
+ logging.info("Parsing first column from %s" % fname)
104
+ sep = sepForFile(fname)
105
+ for line in openFile(fname):
106
+ if not headDone:
107
+ headDone = True
108
+ continue
109
+ geneId = splitOnce(line[:50], sep)[0]
110
+ geneId = geneId.strip("\n").strip("\r").strip()
111
+ #fileGenes.add(geneId.split('.')[0].split("|")[0])
112
+ fileGenes.add(geneId.split("|")[0])
113
+ logging.info("Read %d genes" % len(fileGenes))
114
+ return fileGenes
115
+
116
+ def guessGencodeVersion(fileGenes, signGenes, stripVersion):
117
+ logging.info("Number of genes that are only in a gene model release:")
118
+ infos = []
119
+ if stripVersion:
120
+ fileGenes = set([x.split(".")[0] for x in fileGenes])
121
+
122
+ for version, uniqGenes in signGenes.items():
123
+ if stripVersion:
124
+ uniqGenes = set([x.split(".")[0] for x in uniqGenes])
125
+
126
+ intersection = list(fileGenes.intersection(uniqGenes))
127
+ share = 100.0 * (float(len(intersection)) / len(uniqGenes))
128
+ intLen = len(intersection)
129
+ geneCount = len(uniqGenes)
130
+ infoStr = "release "+version+": %0.2f%%, %d out of %d" % (share, len(intersection), len(uniqGenes))
131
+ if len(intersection)!=0:
132
+ expStr = ", ".join(intersection[:5])
133
+ infoStr += (" e.g. "+ expStr)
134
+ infos.append((share, version, intLen, geneCount, infoStr))
135
+
136
+ infos.sort(reverse=True)
137
+ bestRelease = infos[0][1]
138
+
139
+ for info in infos:
140
+ share, version, intLen, geneCount, infoStr = info
141
+ print(infoStr)
142
+
143
+ return bestRelease
144
+
145
+ def countDots(inGenes):
146
+ " count how many gene names have a dot in them "
147
+ c = 0
148
+ for g in inGenes:
149
+ if "." in g:
150
+ c+=1
151
+ return c
152
+
153
+ def guessNeedsStripping(inGenes):
154
+ " return True if comparisons should be done without version information "
155
+ dotCount = countDots(inGenes)
156
+ if dotCount==len(inGenes):
157
+ logging.info("All gene names have a dot in them. Assuming that input genes have a version")
158
+ stripVersion = False
159
+ elif dotCount==0:
160
+ logging.info("No gene ID has a dot in it. Stripping all version strings for the comparisons.")
161
+ stripVersion = True
162
+ else:
163
+ logging.info("%d input genes have a dot in them, out of %d genes in total. Assuming that genes are symbols and not stripping the part after the dot.." % (dotCount, len(inGenes)))
164
+ stripVersion = True
165
+ return stripVersion
166
+
167
+ def checkGenesAgainstRelease(inGenes, geneType, bestRelease, stripVersion):
168
+ " output how well a release matches the input genes "
169
+ allIds = readGeneSymbols(bestRelease)
170
+ if stripVersion:
171
+ inGenes = set([x.split(".")[0] for x in inGenes])
172
+ allIds = set([x.split(".")[0] for x in allIds])
173
+
174
+ if geneType=="syms":
175
+ #allIds = allIds.values()
176
+ allIds = list(allIds)
177
+ notFoundIds = inGenes - set(allIds)
178
+ print("%d of the genes in the input are not part of %s" % (len(notFoundIds), bestRelease))
179
+ print("Examples: %s" % " ".join(list(notFoundIds)[:50]))
180
+
181
+ def guessGencode(fname, org):
182
+ inGenes = parseGenes(fname)
183
+ stripVersion = guessNeedsStripping(inGenes)
184
+
185
+ inGenes = set(inGenes)
186
+ guessOrg, geneType = guessGeneIdType(inGenes)
187
+ if org is None:
188
+ org = guessOrg
189
+ else:
190
+ logging.info("Organism was provided on command line: %s (no need to guess organism)" % org)
191
+ logging.info("Assuming organism %s, IDs are %s" % (org, geneType))
192
+ signGenes = parseSignatures(org, geneType)
193
+ bestRelease = guessGencodeVersion(inGenes, signGenes, stripVersion)
194
+ print("Best %s Gencode release\t%s" % (org, bestRelease))
195
+
196
+ checkGenesAgainstRelease(inGenes, geneType, bestRelease, stripVersion)
197
+
198
+ def buildSymbolTable(geneType):
199
+ if geneType.startswith("gencode"):
200
+ release = geneType.split("-")[1]
201
+ rows = iterGencodePairs(release)
202
+ else:
203
+ errAbort("unrecognized gene type '%s'" % geneType)
204
+
205
+ outFname = getStaticPath(getGeneSymPath(geneType))
206
+ writeRows(rows, outFname)
207
+
208
+ def iterGencodePairs(release, doTransGene=False):
209
+ " generator, yields geneId,symbol or transId,geneId pairs for a given gencode release"
210
+ # e.g. trackName = "wgEncodeGencodeBasicV34"
211
+ #attrFname = trackName.replace("Basic", "Attrs").replace("Comp", "Attrs")
212
+ #assert(release[1:].isdigit())
213
+ db = "hg38"
214
+ if release[0]=="M":
215
+ db = "mm10"
216
+ if int(release.strip("M"))>=26:
217
+ db='mm39'
218
+ if release in ["7", "14", "17", "19"] or "lift" in release:
219
+ db = "hg19"
220
+ url = "https://hgdownload.cse.ucsc.edu/goldenPath/%s/database/wgEncodeGencodeAttrsV%s.txt.gz" % (db, release)
221
+ logging.info("Downloading %s" % url)
222
+ doneIds = set()
223
+
224
+ lines = downloadUrlLines(url)
225
+ for line in lines:
226
+ row = line.rstrip("\n").split("\t")
227
+
228
+ if doTransGene:
229
+ # key = transcript ID, val is geneId
230
+ key = row[4]
231
+ val = row[0]
232
+ val = val
233
+ else:
234
+ # key = geneId, val is symbol
235
+ key = row[0]
236
+ key = key
237
+ val = row[1]
238
+
239
+ if key not in doneIds:
240
+ yield key, val
241
+ doneIds.add(key)
242
+
243
+ def iterGencodeBed(db, release):
244
+ " generator, yields a BED12+1 with a 'canonical' transcript for every gencode comprehensive gene "
245
+ transToGene = dict(iterGencodePairs(release, doTransGene=True))
246
+
247
+ url = "http://hgdownload.cse.ucsc.edu/goldenPath/%s/database/wgEncodeGencodeCompV%s.txt.gz" % (db, release)
248
+ logging.info("Downloading %s" % url)
249
+ geneToTransList = defaultdict(list)
250
+ for line in downloadUrlLines(url):
251
+ row = tuple(line.split('\t'))
252
+ transId = row[1]
253
+ geneId = transToGene[transId]
254
+ score = int(''.join(c for c in geneId if c.isdigit())) # extract only the xxx part of the ENSGxxx ID
255
+ geneToTransList[geneId].append( (score, row) )
256
+
257
+ logging.info("Picking one transcript per gene")
258
+ for geneId, transList in iterItems(geneToTransList):
259
+ transList.sort() # prefer older transcripts
260
+ canonTransRow = transList[0][1]
261
+ binIdx, name, chrom, strand, txStart, txEnd, cdsStart, cdsEnd, exonCount, exonStarts, exonEnds, score, name2, cdsStartStat, cdsEndStat, exonFrames = canonTransRow
262
+ blockStarts = []
263
+ blockLens = []
264
+ for exonStart, exonEnd in zip(exonStarts.split(","), exonEnds.split(",")):
265
+ if exonStart=="":
266
+ continue
267
+ blockSize = int(exonEnd)-int(exonStart)
268
+ blockStarts.append(exonStart)
269
+ blockLens.append(str(blockSize))
270
+ newRow = [chrom, txStart, txEnd, geneId, score, strand, cdsStart, cdsEnd, exonCount, ",".join(blockLens), ",".join(blockStarts), name2]
271
+ yield newRow
272
+
273
+ def writeRows(rows, outFname):
274
+ with openFile(outFname, "wt") as ofh:
275
+ for row in rows:
276
+ ofh.write("\t".join(row))
277
+ ofh.write("\n")
278
+ logging.info("Wrote %s" % outFname)
279
+
280
+ def buildLocusBed(db, geneType):
281
+ " build a BED file with a 'canonical' transcript for every gene and a json file for it "
282
+ if geneType.startswith("gencode"):
283
+ release = geneType.split("-")[1]
284
+ rows = iterGencodeBed(db, release)
285
+ else:
286
+ errAbort("Unknown gene model type: %s" % geneType)
287
+
288
+ outFname = getStaticPath(getGeneBedPath(db, geneType))
289
+ writeRows(rows, outFname)
290
+
291
+ jsonFname = getStaticPath(getGeneJsonPath(db, geneType))
292
+ bedToJson(db, geneType, jsonFname)
293
+
294
+ def listModelsLocal():
295
+ " print all gene models on local machine "
296
+
297
+ dataDir = join(findCbData(), "genes")
298
+ print("Local cell browser genes data directory: %s" % dataDir)
299
+ fnames = glob.glob(join(dataDir, "*.symbols.tsv.gz"))
300
+ names = [basename(x).split(".")[0] for x in fnames]
301
+ print("Installed gene/symbol mappings:")
302
+ print("\n".join(names))
303
+ print()
304
+
305
+ fnames = glob.glob(join(dataDir, "*.bed.gz"))
306
+ names = [basename(x).replace(".bed.gz","") for x in fnames]
307
+ print("Installed gene/chrom-location mappings:")
308
+ print("\n".join(names))
309
+
310
+ def addFileLocal(fname, name):
311
+ " add a file to the local sym table dir"
312
+ dataDir = join(findCbData(), "genes")
313
+ newFname = name+".symbols.tsv.gz"
314
+ newPath = join(dataDir, newFname)
315
+
316
+ lines = open(fname).readlines()
317
+ ofh = gzip.open(newPath, "wt")
318
+ for l in lines:
319
+ assert("\t" in l) # every line must contain at least one tab character
320
+ l = l.strip() # we're getting DOS and Mac line endings sometimes...
321
+ ofh.write(l)
322
+ ofh.write("\n")
323
+ ofh.close()
324
+ logging.info("Wrote %s" % newPath)
325
+ logging.info("You can now use the value '%s' in your cellbrowser.conf file as a value for geneIdType" % name)
326
+
327
+ def pushLocal():
328
+ " copy all local files to export directory "
329
+ srcDir = join(findCbData(), "genes/")
330
+ targetDir = "/usr/local/apache/htdocs-cells/downloads/cellbrowserData/genes/"
331
+ cmd = ["rsync", "-rvzp", srcDir, targetDir]
332
+ subprocess.run(cmd, check=True)
333
+ logging.info("Updated files in %s" % targetDir)
334
+
335
+ def iterBedRows(db, geneIdType):
336
+ " yield BED rows of gene models of given type "
337
+ fname = getStaticPath(getGeneBedPath(db, geneIdType))
338
+ logging.info("Reading BED file %s" % fname)
339
+ with openFile(fname) as ofh:
340
+ for line in ofh:
341
+ row = line.rstrip("\n\r").split("\t")
342
+ yield row
343
+
344
+ def parseApacheDir(lines):
345
+ fnames = []
346
+ for l in lines:
347
+ hrefCount = l.count("<a href=")
348
+ if hrefCount==1:
349
+ if "Parent Directory<" in l:
350
+ continue
351
+ fname = l.split('<a href="')[1].split('"')[0]
352
+ fnames.append(fname)
353
+ return fnames
354
+
355
+ def listModelRemoteFetch():
356
+ " print all gene models that can be downloaded "
357
+ url = join(getDownloadsUrl(), "genes")
358
+ lines = downloadUrlLines(url)
359
+ fnames = parseApacheDir(lines)
360
+ geneFnames = [f.replace(".bed.gz","") for f in fnames if f.endswith(".bed.gz")]
361
+ symFnames = [f.replace(".symbols.tsv.gz", "") for f in fnames if f.endswith(".symbols.tsv.gz")]
362
+
363
+ sep = "\n"
364
+
365
+ print("Pre-built gene model mapping files available for 'fetch' at %s" % url)
366
+ print(sep.join(geneFnames))
367
+ #for g in geneFnames:
368
+ #print(g.replace(".bed.gz",""))
369
+
370
+ print()
371
+ print("Pre-built geneId/symbol tables available for 'fetch' at %s" % url)
372
+ print(sep.join(symFnames))
373
+ #for g in symFnames:
374
+ #print(g.replace(".symbols.tsv.gz", ""))
375
+
376
+ def listModelRemoteBuild():
377
+ sep = "\n"
378
+ urls = [("hg38", "https://hgdownload.cse.ucsc.edu/goldenPath/hg38/database/"),
379
+ ("mm10", "https://hgdownload.cse.ucsc.edu/goldenPath/mm10/database/"),
380
+ ("mm39", "https://hgdownload.cse.ucsc.edu/goldenPath/mm39/database/"),
381
+ ("hg19", "https://hgdownload.cse.ucsc.edu/goldenPath/hg19/database/")
382
+ ]
383
+
384
+ allNames = defaultdict(list)
385
+ for db, url in urls:
386
+ print()
387
+ print("Files available for 'build' for assembly %s (%s)" % (db, url))
388
+ lines = downloadUrlLines(url)
389
+ fnames = parseApacheDir(lines)
390
+ geneFnames = [x for x in fnames if x.startswith("wgEncodeGencodeAttrs") and x.endswith(".txt.gz")]
391
+ relNames = [x.replace("wgEncodeGencodeAttrsV", "gencode-").replace(".txt.gz", "") for x in geneFnames]
392
+ allNames[db].extend(relNames)
393
+ print(sep.join(relNames))
394
+
395
+ #for db, names in allNames.items():
396
+ #for name in names:
397
+ ##print("%s\t%s" % (db, name))
398
+ #print(name)
399
+
400
+ def keepOnlyUnique(dictSet):
401
+ """ give a dict with key -> set, return a dict with key -> set, but only with elements in the set that
402
+ that don't appear in any other set
403
+ """
404
+ uniqVals = {}
405
+ for key1, origVals in dictSet.items():
406
+ vals = set(list(origVals))
407
+
408
+ for key2 in dictSet.keys():
409
+ if key1==key2:
410
+ continue
411
+ vals = vals - dictSet[key2]
412
+ uniqVals[key1] = vals
413
+
414
+ setList = list(dictSet.values())
415
+ allCommon = set.intersection(*setList)
416
+ return uniqVals, len(allCommon)
417
+
418
+ def writeUniqs(dictSet, outFname):
419
+ " wrote to output file in format <key>tab<comma-sep-list of vals> "
420
+ logging.info("Writing to %s" % outFname)
421
+ with openFile(outFname, "wt") as ofh:
422
+ for key, vals in dictSet.items():
423
+ ofh.write("%s\t%s\n" % (key, "|".join(vals)))
424
+
425
+ def bigSymTable(org):
426
+ """ build one big table that covers all gencode releases for an organism, org can be "mouse" or "human"
427
+ """
428
+ logging.info("Processing: %s" % org)
429
+ infileMask = "gencode*.symbols.tsv.gz"
430
+ dataDir = join(findCbData(), "genes")
431
+ fnames = glob.glob(join(dataDir, infileMask))
432
+
433
+ filtFnames = []
434
+ for fname in fnames:
435
+ baseName = basename(fname)
436
+ # skip weird hg19 files and the big existing tables
437
+ if ("lift" in baseName or "mouse" in baseName or "human" in baseName or "hg19" in baseName):
438
+ continue
439
+ version = baseName.split(".")[0].split("-")[1].lower()
440
+ if (org=="human" and not "m" in version) or \
441
+ (org=="mouse" and "m" in version):
442
+ filtFnames.append((int(version.strip("m")), fname))
443
+
444
+ filtFnames.sort()
445
+
446
+ # read in order, such that new symbols overwrite old ones
447
+ geneToSym = {}
448
+ for idx, fname in filtFnames:
449
+ logging.info("Reading "+fname)
450
+ for line in openFile(fname):
451
+ row = line.rstrip("\n").split("\t")
452
+ geneId, sym = row[:2]
453
+ geneId = geneId.split(".")[0]
454
+ geneToSym[geneId] = sym
455
+
456
+ outFname = getStaticPath(getGeneSymPath("gencode-"+org))
457
+
458
+ writeRows(geneToSym.items(), outFname)
459
+
460
+ def uniqueIds(org):
461
+ """ find unique identifiers in all symbols and geneIds of infileMask and write to
462
+ outBase.{syms,ids}.unique.syms.tsv.gz
463
+ """
464
+ logging.info("Processing: %s" % org)
465
+ infileMask = "gencode*.symbols.tsv.gz"
466
+ dataDir = join(findCbData(), "genes")
467
+ fnames = glob.glob(join(dataDir, infileMask))
468
+ allSyms = {}
469
+ allIds = {}
470
+ for fname in fnames:
471
+ baseName = basename(fname)
472
+ if "lift" in baseName or "mouse" in baseName or "human" in baseName:
473
+ continue
474
+ if org=="human" and "M" in baseName:
475
+ continue
476
+ if org=="mouse" and not "M" in baseName:
477
+ continue
478
+ geneType = basename(fname).split(".")[0]
479
+ logging.info("Reading %s" % fname)
480
+
481
+ syms = set()
482
+ ids = set()
483
+ for line in openFile(fname):
484
+ row = line.rstrip("\n").split("\t")
485
+ geneId, sym = row[:2]
486
+ syms.add(sym)
487
+ ids.add(geneId)
488
+ allSyms[geneType] = syms
489
+ allIds[geneType] = ids
490
+
491
+ # force refseq into this
492
+ syms = []
493
+ fname = getStaticFile("genes/entrez-%s.symbols.tsv.gz" % (org))
494
+ for line in openFile(fname):
495
+ if line.startswith("#"):
496
+ continue
497
+ geneId, sym = line.rstrip("\n").split("\t")
498
+ syms.append(sym)
499
+ allSyms["entrez"] = set(syms)
500
+
501
+ logging.info("Finding unique values")
502
+ uniqSyms, commonSyms = keepOnlyUnique(allSyms)
503
+ uniqIds, commonIds = keepOnlyUnique(allIds)
504
+ logging.info("%d symbols and %d geneIds are shared among all releases" % (commonSyms, commonIds))
505
+
506
+ writeUniqs(uniqSyms, join(dataDir, org+".syms.unique.tsv.gz"))
507
+ writeUniqs(uniqIds, join(dataDir, org+".ids.unique.tsv.gz"))
508
+
509
+ def bedToJson(db, geneIdType, jsonFname):
510
+ " convert BED file to more compact json file: chrom -> list of (start, end, strand, gene) "
511
+ geneToSym = readGeneSymbols(geneIdType)
512
+
513
+ # index transcripts by gene
514
+ bySym = defaultdict(dict)
515
+ for row in iterBedRows(db, geneIdType):
516
+ chrom, start, end, geneId, score, strand = row[:6]
517
+ sym = geneToSym[geneId]
518
+ start = int(start)
519
+ end = int(end)
520
+ transLen = end-start
521
+ rawGeneId = geneId.split(".")[0] # for lookups, we hopefully will never need the version ID...
522
+ fullGeneId = rawGeneId+"|"+sym
523
+ bySym[fullGeneId].setdefault(chrom, []).append( (transLen, start, end, strand, geneId) )
524
+
525
+ symLocs = defaultdict(list)
526
+ for geneId, chromDict in bySym.items():
527
+ for chrom, transList in chromDict.items():
528
+ transList.sort(reverse=True) # take longest transcript per chrom
529
+ _, start, end, strand, transId = transList[0]
530
+ symLocs[chrom].append( (start, end, strand, geneId) )
531
+
532
+ sortedLocs = {}
533
+ for chrom, geneList in symLocs.items():
534
+ geneList.sort()
535
+ sortedLocs[chrom] = geneList
536
+
537
+ ofh = open(jsonFname, "wt")
538
+ outs = json.dumps(sortedLocs)
539
+ #md5 = hashlib.md5(outs.encode("utf8")).hexdigest()[:10]
540
+ ofh.write(outs)
541
+ ofh.close()
542
+ logging.info("Wrote %s" % jsonFname)
543
+ logging.info("If this is a new .json file and you are on hgwdev, copy it now to /usr/local/apache/htdocs-cells/downloads/cellbrowserData/genes/ and note this directory for the dataset release push to the RR. The reason is that users may want to cbBuild using this gene transcript set and that is easier if we provide the .json file")
544
+
545
+ #fileInfo[code] = {"label":label, "file" : jsonFname, "md5" :md5}
546
+
547
+ def buildGuessIndex():
548
+ " read all gene model symbol files from the data dir, and output <organism>.unique.tsv.gz "
549
+ dataDir = join(findCbData(), "genes")
550
+ uniqueIds("human")
551
+ uniqueIds("mouse")
552
+ bigSymTable("human")
553
+ bigSymTable("mouse")
554
+
555
+ def fetch(fileDesc):
556
+ " download symbol or gene files to local dir "
557
+ if "." in fileDesc:
558
+ # user wants a gene model file
559
+ ext = "bed.gz"
560
+ else:
561
+ ext = "symbols.tsv.gz"
562
+ fname = getStaticFile("genes/%s.%s" % (fileDesc, ext), verbose=True)
563
+ return
564
+
565
+ def cbGenesCli():
566
+ args, options = cbGenes_parseArgs()
567
+
568
+ command = args[0]
569
+ if command=="guess":
570
+ fname = args[1]
571
+ org = None
572
+ if len(args)==3:
573
+ org = args[2]
574
+ guessGencode(fname, org)
575
+
576
+ elif command == "check":
577
+ fname = args[1]
578
+ release = args[2]
579
+ inGenes = parseGenes(fname)
580
+ guessOrg, geneType = guessGeneIdType(inGenes)
581
+ stripVersion = guessNeedsStripping(inGenes)
582
+ checkGenesAgainstRelease(inGenes, geneType, release, stripVersion)
583
+
584
+ elif command=="fetch":
585
+ if len(args)==1:
586
+ listModelRemoteFetch()
587
+ else:
588
+ arg = args[1]
589
+ fetch(arg)
590
+
591
+ elif command=="syms": # undocumented
592
+ geneType = args[1]
593
+ buildSymbolTable(geneType)
594
+
595
+ elif command=="build":
596
+ if len(args)==1:
597
+ listModelRemoteBuild()
598
+ else:
599
+ db, geneType = args[1:]
600
+ buildSymbolTable(geneType)
601
+ buildLocusBed(db, geneType)
602
+
603
+ elif command=="ls":
604
+ listModelsLocal()
605
+
606
+ elif command=="index":
607
+ buildGuessIndex()
608
+
609
+ elif command=="allSyms":
610
+ org = args[1]
611
+ bigSymTable(org)
612
+
613
+ elif command=="add":
614
+ addFileLocal(args[1], args[2])
615
+
616
+ elif command=="push":
617
+ pushLocal()
618
+
619
+ elif command=="json": # undocumented
620
+ db, geneType, outFname = args[1:]
621
+ bedToJson(db, geneType, outFname)
622
+ else:
623
+ errAbort("Unrecognized command: %s" % command)
624
+