Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Experiments

experimenting.livemd

Experiments

Mix.install([
  {:httpoison, "~> 2.2.1"},
  {:jason, "~> 1.4"},
  {:kino, "~> 0.12.0"},
  {:biolex, path: Path.dirname(__ENV__.file) <> "/biolex"}
])

Config

notebook_path = Path.dirname(__ENV__.file) <> "/"
alias Biolex.NCBI, as: NCBI
alias Biolex.Fasta, as: Fasta
{:ok, env} = Biolex.Env.reload(notebook_path <> ".env")
env
defmodule Runner do
  def download_sequence(gene_id, :nucleotid) do
    {:ok, ids} = NCBI.get_links(gene_id, "gene", "nuccore", "gene_nuccore")

    Task.async_stream(
      ids,
      fn id ->
        {:ok, fasta} = NCBI.get_sequence(id)
        fasta
      end,
      timeout: :infinity
    )
    |> Enum.map(fn {:ok, fasta} ->
      {:ok, parse} = Fasta.parse(fasta)
      parse
    end)
    |> Enum.to_list()
  end

  def download_sequence(gene_id, :protein) do
    {:ok, ids} = NCBI.get_links(gene_id, "gene", "protein", "gene_protein")

    Task.async_stream(
      ids,
      fn id ->
        {:ok, fasta} = NCBI.get_sequence(id, "protein")
        fasta
      end,
      timeout: :infinity
    )
    |> Enum.map(fn {:ok, fasta} ->
      {:ok, parse} = Fasta.parse(fasta)
      parse
    end)
    |> Enum.to_list()
  end

  def download_sequence(query, :search, opts \\ []) do
    {:ok, _json, {web_env, query_key, _ids}} =
      NCBI.search(query, opts)

    opts = Keyword.merge([webenv: web_env, query_key: query_key], opts)
    {:ok, fasta_all} = NCBI.fetch(opts)
    fasta_all
    # fasta_all
    # |> String.trim("\n")
    # |> String.split("\n\n")
    # |> Enum.map(fn fasta ->
    #   {:ok, parse} = Fasta.parse(fasta)
    #   parse
    # end)
  end
end

Search

default_input = ~s("CRY1"[Gene Name] AND insects[Organism])
kino_query = Kino.Input.textarea("Query", default: default_input) |> Kino.render()
kino_filter = Kino.Input.checkbox("Filter", default: false) |> Kino.render()
kino_file_name = Kino.Input.text("Filename", default: "result.fasta") |> Kino.render()
Kino.nothing()
query = Kino.Input.read(kino_query)

downloaded_fastas =
  Runner.download_sequence(
    query,
    :search,
    db: "nuccore",
    retmax: 20,
    timout: 50000
  )
do_filter = Kino.Input.read(kino_filter)
filter_fn = fn entry -> !String.contains?(entry.meta, "whole genome") end

fastas =
  if do_filter do
    downloaded_fastas |> Enum.filter(filter_fn)
  else
    downloaded_fastas
  end
file_name = Kino.Input.read(kino_file_name)
# fasta_string = Enum.map(fastas, fn fasta -> Fasta.to_string(fasta) end) |> Enum.join("\n")
File.write("#{notebook_path}downloads/#{file_name}", fastas)
fastas |> length()

Nucleotid from Gene ID

gene_id = "113500526"
downloaded_fastas = Runner.download_sequence(gene_id, :nucleotid)
do_filter = true
filter_fn = fn entry -> !String.contains?(entry.meta, "whole genome") end

fastas =
  if do_filter do
    downloaded_fastas |> Enum.filter(filter_fn)
  else
    downloaded_fastas
  end
fasta_string = Enum.map(fastas, fn fasta -> Fasta.to_string(fasta) end) |> Enum.join("\n")
File.write("#{notebook_path}downloads/gene2nuc_#{gene_id}.fasta", fasta_string)

Protein from Gene ID

gene_id = "105267484"
downloaded_fastas = Runner.download_sequence(gene_id, :protein)
do_filter = true
filter_fn = fn entry -> !String.contains?(entry.meta, "whole genome") end

fastas =
  if do_filter do
    downloaded_fastas |> Enum.filter(filter_fn)
  else
    downloaded_fastas
  end
fasta_string = Enum.map(fastas, fn fasta -> Fasta.to_string(fasta) end) |> Enum.join("\n")
File.write("#{notebook_path}downloads/gene2prot_#{gene_id}.fasta", fasta_string)

TODO

{:ok, agent} = Agent.start_link(fn -> [] end)

display = Kino.Frame.new()

form =
  Kino.Control.form(
    [name: Kino.Input.text("NBCI Gene ID")],
    submit: "Submit"
  )

output = Kino.Frame.new()
Kino.Frame.append(display, form)
Kino.Frame.append(display, output)

Kino.listen(form, fn event ->
  id = event[:data][:name]

  start_time = System.monotonic_time()
  Kino.Frame.render(output, "Loading...")

  res = Runner.download_sequence(id, :nucleotid)

  end_time = System.monotonic_time()
  elapsed_time = System.convert_time_unit(end_time - start_time, :native, :millisecond)

  Kino.Frame.clear(output)
  Kino.Frame.append(output, "Done... #{elapsed_time}ms")
  Kino.Frame.append(output, res)

  Agent.update(agent, fn _ -> res end)
end)

# example 113500526
display
form =
  Kino.Control.form(
    [
      name: Kino.Input.text("Name")
    ],
    submit: "Submit"
  )

Kino.listen(form, fn event ->
  IO.inspect(Agent.get(agent, fn state -> state end))
  IO.inspect(event)
end)

form