Skip to content

Instantly share code, notes, and snippets.

@alexpreynolds
Last active December 2, 2024 18:24
Show Gist options
  • Save alexpreynolds/0de91f2723b552aa904540d00ef14b98 to your computer and use it in GitHub Desktop.
Save alexpreynolds/0de91f2723b552aa904540d00ef14b98 to your computer and use it in GitHub Desktop.
Automate generating PNG or SVG snapshots of regions in the Fiberscope browser
#!/usr/bin/env python
import os
import sys
import time
from pathlib import Path
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
chrome_options = Options()
chrome_options.add_argument('headless')
chrome_options.add_argument('no-sandbox')
chrome_options.add_argument('disable-dev-shm-usage')
chrome_options.add_argument('enable-webgl-image-chromium')
chrome_options.add_argument('disable-application-cache')
chrome_options.add_argument('start-maximized')
# set download directory
home_dir = Path.home()
download_dir = os.path.join([home_dir, 'Downloads', 'Fiberscope'])
Path(download_dir).mkdir(parents=True, exist_ok=True)
prefs = {'download.default_directory' : download_dir}
chrome_options.add_experimental_option('prefs', prefs)
# snapshot parameters
browser_width = 1024
browser_height = 1280
# allowed cluster_events: m6Aplus, m6Aminus, 5mCplus, 5mCminus, 5hmCplus, 5hmCminus
intervals = [
{
'browser': 'chr2:10120061-10124494',
'cluster_subregion': 'chr2:10121870-10122831',
'cluster_events': 'm6Aplus_m6Aminus_5mCplus_5mCminus',
},
{
'browser': 'chr4:17573874-17580704',
'cluster_subregion': 'chr4:17576806-17577618',
'cluster_events': 'm6Aplus_m6Aminus_5mCplus_5mCminus',
},
]
mode = 'CD3+_D2_HAP1_Stim_052824'
site_loading_delay = 5 # seconds
rendering_delay = 15 # seconds
export_delay = 5 # seconds
# export PNG (P) or SVG (S) via Fiberscope keybinding
key_to_export = 'P'
# key_to_export = 'S'
print('Exporting snapshots to [{}]'.format(download_dir))
for interval in intervals:
browser_interval = interval['browser']
subregion_interval = interval['cluster_subregion'] if 'cluster_subregion' in interval else None
subregion_events = interval['cluster_events'] if 'cluster_events' in interval else None
print('Exporting snapshot for genomic interval [{}]'.format(browser_interval))
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=chrome_options)
driver.set_window_size(browser_width, browser_height)
fiberscope_url = 'https://explore.altius.org/fsv.dev'
browser_url = '{}/?interval={}&mode={}'.format(fiberscope_url, browser_interval, mode)
if subregion_interval:
browser_url += '&clusterInterval={}'.format(subregion_interval)
if subregion_events:
browser_url += '&clusterEvents={}'.format(subregion_events)
driver.get(browser_url)
try:
hg = WebDriverWait(driver, site_loading_delay).until(EC.presence_of_element_located((By.CLASS_NAME, 'higlass')))
time.sleep(rendering_delay) # longer delays required for Chrome on macOS due to Metal WebGL rendering issues
element = driver.find_element('xpath', '/html/body')
ActionChains(driver).move_to_element(element).click(element).key_down(Keys.ALT).send_keys(key_to_export).key_up(Keys.ALT).perform()
time.sleep(export_delay)
except TimeoutException:
sys.stderr.write("Error: Loading Fiberscope took too much time!")
sys.exit(1)
driver.close()
@alexpreynolds
Copy link
Author

alexpreynolds commented Nov 27, 2024

Some steps needed to set up chromedriver, selenium, and the webdriver dependencies on Mac OS X (may require Xcode and Homebrew, if not already installed):

sudo xcodebuild -license accept
brew install --cask chromedriver
pip install selenium
pip install webdriver-manager

If necessary:

pip install webdriver-manager --upgrade

If Homebrew can't be installed, it may be helpful to get chromedriver from here: https://googlechromelabs.github.io/chrome-for-testing/ but its version may need to match the installed version of Chrome on your device.

Note: At this time (27 Nov 2024), Google Chrome on Mac OS X includes a poor WebGL implementation. I don't yet know what experimental option to add to chrome_options to set the Chrome experimental flag that fixes this in a non-headless Mac OS X environment. Therefore, if blank or incomplete screenshots are seen, it may be necessary to increase the value of rendering_delay in the script to account for more complex modes or larger genomic regions, in order to give the headless browser more time to render a view before a snapshot is taken. This should not affect Windows users, because the WebGL renderer in Chrome on that platform uses OpenGL and not Apple's Metal engine. Another potential option on Mac OS X would be to use a Firefox-based Selenium automation script, as Firefox uses OpenGL ES and not Metal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment