9653a73b90b6

Add bioinformatics, hexdump
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Fri, 02 Oct 2026 11:39:24 -0400
parents d05f5412e9aa
children 0711b20b976c
branches/tags (none)
files losh.asd make-docs.lisp src/bioinformatics.lisp src/debugging.lisp src/package.lisp

Changes

--- a/losh.asd	Tue Nov 11 14:34:11 2025 -0500
+++ b/losh.asd	Fri Oct 02 11:39:24 2026 -0400
@@ -30,6 +30,7 @@
                  (:file "base" :depends-on ("package"))
 
                  ;; 0 ---------------------------------------------------------
+                 (:file "bioinformatics" :depends-on ("base"))
                  (:file "chili-dogs" :depends-on ("base"))
                  (:file "clos" :depends-on ("base"))
                  (:file "eldritch-horrors" :depends-on ("base"))
@@ -75,6 +76,7 @@
                                                  "mutation"))
                  (:file "debugging" :depends-on ("control-flow"
                                                  "math"
+                                                 "shell"
                                                  "hash-tables"))
 
                  ;; 5 ---------------------------------------------------------
--- a/make-docs.lisp	Tue Nov 11 14:34:11 2025 -0500
+++ b/make-docs.lisp	Fri Oct 02 11:39:24 2026 -0400
@@ -3,9 +3,10 @@
 (defparameter *document-packages*
   (list "LOSH"
 
+        "LOSH.ARRAYS"
         "LOSH.ASTAR"
-        "LOSH.ARRAYS"
         "LOSH.BASE"
+        "LOSH.BIOINFORMATICS"
         "LOSH.BITS"
         "LOSH.CHILI-DOGS"
         "LOSH.CLOS"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/bioinformatics.lisp	Fri Oct 02 11:39:24 2026 -0400
@@ -0,0 +1,88 @@
+(in-package :losh.bioinformatics)
+
+
+(defun nxx (data n key)
+  (if (alexandria:emptyp data)
+    0
+    (let* ((lengths (sort (map 'vector key data) #'>))
+           (total (reduce #'+ lengths))
+           (target (* total n)))
+      (loop :with x = 0
+            :for l :across lengths
+            :do (incf x l)
+            :when (>= x target) :do (return l)))))
+
+(defun n50 (data &key (key #'identity))
+  "Return the N50 statistic of `data`.
+
+  `key` will be called on each element of `data` and should return the length
+  of each datum.
+
+  An empty `data` will return an N50 of `0`.
+
+  Examples:
+
+    (n50 (list 2 3 4 5 6 7 8 9 10))
+    ;; => 8
+
+    (n50 (vector \"ACTACCAT\"
+                 \"CAGAC\"
+                 \"GCTT\"
+                 \"CCCCCCC\"
+                 \"CCAACCAAA\"
+                 \"CA\")
+         :key #'length)
+    ;; => 7
+
+  "
+  (nxx data 0.5d0 key))
+
+(defun n90 (data &key (key #'identity))
+  "Return the N90 statistic of `data`.
+
+  `key` will be called on each element of `data` and should return the length
+  of each datum.
+
+  An empty `data` will return an N90 of `0`.
+
+  Examples:
+
+    (n90 (list 2 3 4 5 6 7 8 9 10))
+    ;; => 4
+
+    (n90 (vector \"ACTACCAT\"
+                 \"CAGAC\"
+                 \"GCTT\"
+                 \"CCCCCCC\"
+                 \"CCAACCAAA\"
+                 \"CA\")
+         :key #'length)
+    ;; => 4
+
+  "
+  (nxx data 0.9d0 key))
+
+
+(defparameter *x*
+  (list
+    990 990 990
+    2500
+    10000 12000 12000 14000
+    )
+  )
+
+(defparameter *y*
+  (list
+    23 10 99
+    7938
+    6000 6000 12000 21400
+    )
+  )
+
+(list
+  (float (alexandria:mean *x*))
+  (n50 *x*)
+  '--
+  (float (alexandria:mean *y*))
+  (n50 *y*)
+  )
--- a/src/debugging.lisp	Tue Nov 11 14:34:11 2025 -0500
+++ b/src/debugging.lisp	Fri Oct 02 11:39:24 2026 -0400
@@ -74,6 +74,11 @@
   (format stream "~v,'0X" (/ size 4) n)
   (values))
 
+(defun hexdump (bytes)
+  "Dump `bytes` to standard out by shelling out to `xeh`."
+  (write-string (sh (list "xeh") :input bytes :result-type 'string))
+  (values))
+
 (defmacro shut-up (&body body)
   "Run `body` with stdout and stderr redirected to the void."
   `(let ((*standard-output* (make-broadcast-stream))
@@ -242,4 +247,3 @@
   `(iterate (repeat ,n)
      (collect (progn ,@body))))
 
-
--- a/src/package.lisp	Tue Nov 11 14:34:11 2025 -0500
+++ b/src/package.lisp	Fri Oct 02 11:39:24 2026 -0400
@@ -115,6 +115,13 @@
   (:export
     :with-eof-handled))
 
+(defpackage :losh.bioinformatics
+  (:use :cl :iterate :losh.base)
+  (:documentation "Utilities related to bioinformatics.")
+  (:export
+    :n50
+    :n90))
+
 
 (defpackage :losh.io
   (:use :cl :iterate :losh.base)
@@ -439,6 +446,7 @@
 (defpackage :losh.debugging
   (:use :cl :iterate :losh.base
     :losh.math
+    :losh.shell
     :losh.control-flow
     :losh.hash-tables)
   (:documentation "Utilities for figuring out what the hell is going on.")
@@ -454,6 +462,7 @@
     :dis
     :gimme
     :hex
+    :hexdump
     :phr
     :pr
     :pretty-print-hash-table
@@ -500,6 +509,7 @@
    :losh.arrays
    :losh.astar
    :losh.base
+   :losh.bioinformatics
    :losh.bits
    :losh.chili-dogs
    :losh.clos