Mercurial > rlm
view src/rlm/dna_melting.clj @ 0:78a630e650d2
initial import
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Tue, 18 Oct 2011 00:57:08 -0700 |
parents | |
children |
line wrap: on
line source
1 (ns rlm.dna-melting2 (:refer-clojure :only [])3 (:require rlm.ns-rlm mobius.base))4 (rlm.ns-rlm/ns-clone mobius.base)5 (use :reload-all 'rlm.web-stuff)8 (def pre "/home/r/MIT/6/6.122/DNA/samples/")12 (defrecord dna-data [temp glow name temp-units glow-units]13 clojure.lang.IFn14 (invoke [this k] (get this k))15 (invoke [this k not-found] (get this k not-found))16 (toString [this] "whatever"))18 (defmethod print-method dna-data [d w]19 (.write w (.toString d)))21 (defmethod print-dup dna-data [d w]22 (print-method d w))24 (defn load-data [source]25 (let [data (read-dataset source :delim \tab)26 temp (vec ($ :col0 data))27 glow (vec ($ :col1 data))]28 (dna-data. temp glow29 (last (re-split #"/" source))30 "Raw Temperature (Volts)"31 "Raw Glow (Volts)")))34 (def ?-1 (load-data (str pre "sample4-1.txt")))36 ;; I accidentally removed the cuvette while it was still recording!37 ;; drop last 5 seconds of invalid data!38 (def ?-2* (load-data (str pre "sample4-2.txt")))39 (def ?-2 (assoc ?-2*40 :temp (drop-last 500 (:temp ?-2*))41 :glow (drop-last 500 (:glow ?-2*))))43 (def ?-3 (load-data (str pre "sample4-3.txt")))44 (def A-1 (load-data (str pre "sampleA-1.txt")))45 (def A-2 (load-data (str pre "sampleA-2.txt")))46 (def A-3 (load-data (str pre "sampleA-3.txt")))47 (def B-2 (load-data (str pre "sampleB-2.txt")))48 (def B-3 (load-data (str pre "sampleB-3.txt")))49 (def C-1 (load-data (str pre "sampleC-1.txt")))50 (def C-2 (load-data (str pre "sampleC-2.txt")))51 (def C-3 (load-data (str pre "sampleC-3.txt")))54 (def pure-bleaching (load-data (str pre "sampleB-1(failed-to-heat).txt")))55 (def double-cycle (load-data (str pre "sampleC-3(double).txt")))56 (def triple-cycle (load-data (str pre "sampleC-3(triple).txt")))58 (def all-samples59 [?-1 ?-3 A-1 A-2 A-3 B-2 B-3 C-1 C-2 C-3])61 (def everything62 (concat [pure-bleaching double-cycle triple-cycle] all-samples))66 (defn dna-plot [d]67 (view68 (->69 (visual (:temp d))70 (set-y-label (:temp-units d))71 (set-x-label "Time (deci-seconds)")72 (set-title (:name d))))73 (view74 (->75 (visual (:glow d))76 (set-y-label (:glow-units d))77 (set-x-label "Time (deci-seconds)")78 (set-title (:name d))))79 d)81 (defn dna-melting [d]83 (->84 (scatter-plot (:temp d) (:glow d))85 (set-y-label (:glow-units d))86 (set-x-label (:temp-units d))87 (set-title (:name d))))90 (defmethod visual clojure.lang.LazySeq [ls]91 (visual (vec ls)))93 (defmethod visual clojure.lang.PersistentVector [v]94 (set-y-range (xy-plot (vec (range (count v))) v)95 (apply min v) (apply max v)))97 (defmethod visual dna-data [d]98 (dna-plot d))105 ;;; Filter V_RTD and V_F to reduce noise109 ;(let [a (int 1.8e4) b (int 2.2e4)]110 ; (visual (map (vec (temperature triple-cycle)) (range a b)))111 ; (visual (map (vec (dna-fraction triple-cycle)) (range a b))))113 ;; Differentiate the resulting function with respect to temperature.115 (def test-temp-range (vec (range 260 380 0.1)))117 (defn trans-print [& args] (apply println args) args)119 ;; (def search120 ;; #(for [x (range -1000 1000 100) y (range -1000 1000 100)]121 ;; (do122 ;; (print [x y])123 ;; (try (trans-print (non-linear-model124 ;; (ideal-dna-fraction 30e-6)125 ;; test-dna-fraction test-temperature [x y]126 ;; :method :newton-raphson))128 ;; (catch Exception e (trans-print nil))))))131 ;;(non-linear-model (ideal-dna-fraction 30e-6) test-dna-fraction test-temperature [-184 -71e3])133 ;;(time (def answer (non-linear-model (ideal-dna-fraction 30e-6) test-dna-fraction test-temperature [-200 -90e3])))135 ;;we're assuming that the SYBR Green 1 doesn't glow at all when there is only136 ;;single stranded DNA, but it actually does. V_f only ever gets down to ~0.1 V137 ;;even with everything melted.140 ;;correct for thermal capacatance142 (defn find-max [v]143 (first (reduce (fn [a b] (if (> (last b) (last a)) b a)) (indexed v))))145 (defn find-min [v]146 (first (reduce (fn [a b] (if (< (last b) (last a)) b a)) (indexed v))))148 (defn plot-thermal-delay []149 (let [a (int 2.5e3) b (int 5e3)]150 (dna-plot (assoc A-1151 :temp (map (vec (:temp A-1)) (range a b))152 :glow (map (vec (:glow A-1)) (range a b))))))154 (defvar thermal-delay155 (let [a (int 2.5e3) b (int 5e3)]156 (-157 (find-min (map (vec (:glow A-1)) (range a b)))158 (find-max (map (vec (:temp A-1)) (range a b)))))159 "There are two sources of thermal delay: thermal capacatance160 of the cuvette holder and thermal capacatance from the time161 it takes DNA to unwind.163 Use A-1 to find the thermal delay. There was almost no delay164 between heating and cooling for A-1, and thus the extremum of165 temperature and glow should temporally coincide if there were166 no delays. It turns out that there is about a 30 second lag!" )168 (defn thermal-delay-correction*169 "There is a certain delay between the RTD reporting changes in170 temperature and the temperature of the DNA actually changing.171 This shifts the temperature values so that the delay is eliminated."172 [thermal-delay #^dna-data d]173 (assoc d174 :name (str (:name d) " |thermal-correction| ")175 :temp (drop-last thermal-delay (:temp d))176 :glow (drop thermal-delay (:glow d))))178 (def thermal-delay-correction (partial thermal-delay-correction* thermal-delay))180 ;;correct for photo-bleaching182 (defn general-linear [[A B] x] (+ (* A x) B))184 (defvar bleaching-coef nil185 ;; (let [[A B]186 ;; (:coefs187 ;; (let [a (int 3e4) b (length (:glow pure-bleaching))]188 ;; (non-linear-model189 ;; general-linear190 ;; (map (vec (:glow pure-bleaching)) (range a b))191 ;; (range a b)192 ;; [1 1])))]193 ;; A)194 "This function corrects V_f for photo-bleaching over a period of time.195 Photo-bleaching was found to be linear(!) over quite a long period of time.196 Data is taken from sample B-1, which I left in the holder for an hour197 with no heating")199 (defn bleaching-correction*200 [bleaching-coef #^dna-data d]201 ;;the correction is clibrated to apply to the raw data only202 (assert (= (:glow-units d) "Raw Glow (Volts)"))203 ;;we need to modulate this correction factor205 (let [baseline (first (drop 3e4 (:temp pure-bleaching)))]206 (assoc d207 :name (str (:name d) " |bleaching-correction| ")208 :glow (map (fn [[i n]] (- n (*209 (/ n baseline)210 ((partial general-linear [bleaching-coef 0]) i))))211 (indexed (:glow d))))))213 (def bleaching-correction (partial bleaching-correction* bleaching-coef))215 ;; compensate for residual fluorescence when everything is melted217 (defn residual-fluorescence218 "the SYBR1 green dye doesn't completly stop glowing once everything219 is melted."220 [#^dna-data d]221 (let [low (apply min (:glow d))222 high (apply max (:glow d))]223 (assoc d224 :name (str (:name d) " |residual-fluorescence| ")225 :glow (map (fn [f]226 (- f (* (- 1 (/ f high)) low))) (:glow d)))))231 ;; extract the cooling phase233 (defn cooling-phase234 "first stretch where the temperature is going down for a while235 equivalent to where the f curve starts to recover"236 [#^dna-data d]237 (let [t (:temp d)238 f (:glow d)239 dividing-line (reduce (fn [a b] (if (< (a 1) (b 1)) a b)) (indexed f))240 t-new (drop (dividing-line 0) t)241 f-new (drop (dividing-line 0) f)]242 (assoc d243 :name (str (:name d) " |extract cooling| ")244 :temp (vec t-new) :glow (vec f-new))))248 ;; filter noise249 ;;(http://clojure-log.n01se.net/date/2009-10-13.html by ambient250 ;;this is such a cool transform!!!253 (defn lo-pass254 [d coll]255 (reductions #(+ (* %2 d) (* %1 (- 1.0 d))) coll))258 ;;)260 (def reasonable-low-pass (partial lo-pass 1e-2))262 (defn low-pass-correction263 "filter the raw data through a low pass filter to remove264 electronic noise"265 [#^dna-data d]266 (assert (= (:glow-units d) "Raw Glow (Volts)"))267 (assert (= (:temp-units d) "Raw Temperature (Volts)"))268 (assoc d269 :name (str (:name d) " |low-pass| ")270 :temp (reasonable-low-pass (:temp d))271 :glow (reasonable-low-pass (:glow d))))277 ;; correct for units279 (defn RTD-voltage->temperature280 "transform RTD voltage to temperature.281 R_RTD = 1000 + 3.85 * (T - 273)282 T = ((R_RTD - 1000) / 3.85 ) + 273283 V_RTD = 15 * R_RTD / (R + R_RTD)284 R_RTD = R / (15/V_RTD - 1)"285 [coll]286 (let [R 14.97e3287 V 15]288 (letfn [(T [R_RTD] (+ 273 (/ (- R_RTD 1000) 3.85))) ;; from lab notrd289 (R_RTD [V_RTD] (/ R (- (/ V V_RTD) 1)))]290 (map (comp T R_RTD) coll))))292 (defn normalize293 "Transform photodiode current to relative fluorescence."294 [coll]295 (let [low (apply min coll)296 high (apply max coll)]297 (map #(/ (- % low) (- high low)) coll)))299 (defn unit-transform300 "turn raw voltage into temperature and dna-concentration"301 [#^dna-data d]302 (assert (= (:glow-units d) "Raw Glow (Volts)"))303 (assert (= (:temp-units d) "Raw Temperature (Volts)"))304 (assoc d305 :name (str (:name d) " |units| ")306 :temp-units "Temperature (Kelvin)"307 :glow-units "DNA-Fracton"308 :temp (RTD-voltage->temperature (:temp d))309 :glow (normalize (:glow d))))312 (defn temp-unit-transform313 "turn raw voltage into temperature and dna-concentration"314 [#^dna-data d]315 (assert (= (:temp-units d) "Raw Temperature (Volts)"))316 (assoc d317 :name (str (:name d) " |temp-units| ")318 :temp-units "Temperature (Kelvin)"319 :temp (RTD-voltage->temperature (:temp d))))321 (defn glow-unit-transform322 "turn raw voltage into temperature and dna-concentration"323 [#^dna-data d]324 (assert (= (:glow-units d) "Raw Glow (Volts)"))325 (assoc d326 :name (str (:name d) " |glow-units| ")327 :glow-units "DNA-Fracton"328 :glow (normalize (:glow d))))331 (defn thermal-efficiency332 [#^dna-data d]333 (assert (= (:temp-units d) "Temperature (Kelvin)"))334 (assert (= (:glow-units d) "Raw Glow (Volts)"))335 (assoc d336 :name (str (:name d) " |thermal-efficiency| ")337 :glow nil))341 (defn remove-first-values342 "remove the first minute or so of data so that the initial temperature of343 the cuvette itself doesn't matter"344 [#^dna-data d]345 (assoc d346 :name (str (:name d) " |remove-first| ")347 :temp (drop 600 (:temp d))348 :glow (drop 600 (:glow d))))350 (defn diff [coll] (map - (rest coll) coll ))351 (defn temp-transform352 "my assumption will be that at the very end of the temperature data, the353 cuvette is exactly the same temperature as the RTD. Then, I use newton's354 heat transfer and numerical integration to derive the heat of the cuvette355 for previous times"356 [k-value temperature-data]357 (let [T1 (vec (reverse temperature-data))358 ;; want fast indexed access, and instead of doing the problem in reverse359 ;; just reverse the vector at the start, treat it normally, and360 ;; then reverse at the end361 initial-cuvette-temp (first T1)362 initial-RTD-temp (first T1)363 step (fn [prev-T2 current-T1]364 (let [new-T2 (+ prev-T2 (* k-value (- current-T1 prev-T2)))]365 new-T2))]366 (reverse (reductions step initial-cuvette-temp T1))))368 (def k-value 0.1)370 (defn temp-corr-2 [k-value T1*]371 (let [T1 (reverse T1*)]372 (reverse (cons (first T1) (map + (map (partial * k-value) (diff T1)) (rest T1))))))374 (defn temp-corr-3 [initial-cuvette-temp k-value T1]375 (let [step376 (fn [prev-T2 current-T1]377 (+ prev-T2 (* k-value (- current-T1 prev-T2))))]378 (rest (reductions step initial-cuvette-temp T1))))380 (defn newton-temp-correction* [k-value #^dna-data d]381 (assoc d382 :name (str (:name d) " |newton-temp| ")383 :temp (temp-transform k-value (:temp d))))384 (defn newton-temp-correction2* [k-value #^dna-data d]385 (assoc d386 :name (str (:name d) " |newton-temp-reverse| ")387 :temp (temp-corr-2 k-value (:temp d))))388 (defn newton-temp-correction3* [init-temp k-value #^dna-data d]389 (assoc d390 :name (str (:name d) " |newton-temp-reverse| ")391 :temp (temp-corr-3 init-temp k-value (:temp d))))393 (defn turn-e [n] (format "%5.2e" n))395 (defn newton-temp-correction4*396 "now with AIR!!!"397 [k-block-sample k-sample-air initial-sample-temp room-temp #^dna-data d]398 (let [old-temp (:temp d)399 step (fn [prev-T2 current-T1]400 (+ prev-T2401 (* k-block-sample (- current-T1 prev-T2))402 (* k-sample-air (- room-temp prev-T2))))403 new-temp (rest (reductions step initial-sample-temp old-temp))]404 (assoc d405 :name (str (:name d)406 " |temp-adjusted {"407 "initial-sample:" (turn initial-sample-temp) " "408 "room-temp:" (turn room-temp) " "409 "k-block-sample:" (turn-e k-block-sample) " "410 "k-sample-air:" (turn-e k-sample-air) "}")411 :temp new-temp)))413 (defn plot-adjusted-temp414 "visualize the temperature correction"415 [adjuster #^dna-data d]416 (view417 (add-lines418 (visual (:temp d))419 (vec (range (count (:temp d))))420 (vec (:temp (adjuster d))))))426 ;; process data428 (defn process [#^dna-data d]429 (cooling-phase430 (unit-transform431 (residual-fluorescence432 (bleaching-correction433 (low-pass-correction434 ;(thermal-delay-correction435 d))))))438 (defn first-pass439 "after this, the only thing stopping the melting curve from440 being a straight line is thermal capacatance"441 [#^dna-data data]442 (low-pass-correction443 ;(remove-first-values444 (bleaching-correction445 data)))449 (defn explore [k-value]450 (dna-melting (newton-temp-correction* k-value (first-pass A-2))))453 (defn explore2 [k-value]454 (dna-melting (newton-temp-correction2* k-value (first-pass A-2))))457 (defn explore3 [init-temp k-value]458 (dna-melting (newton-temp-correction3* init-temp k-value (unit-transform (first-pass A-2)))))462 ;; get the three characteristic values we want.464 (defn ideal-dna-fraction* [concentration [delta-S delta-H] temperature]465 (let [R 8.31447215466 t temperature467 Ct concentration468 K_eq (exp (- (/ delta-S R) (/ delta-H (* R t))))469 f (/470 (+ 1 (* Ct K_eq)471 (- (sqrt (+ 1 (* 2 Ct K_eq)))))472 (* Ct K_eq))]473 f))475 (def ideal-dna-fraction (partial ideal-dna-fraction* 30e-6))477 (defvar starting-values478 ;; [-184 -71e3]479 [-904 -32e4]480 "chosen from theoritical estimation")483 (defn analyze* [iterations #^dna-data d]484 (let [best-fit-results485 (non-linear-model486 ideal-dna-fraction487 (:glow d)488 (:temp d)489 starting-values490 :max-iter iterations)]491 best-fit-results))494 (def analyze (partial analyze* 200))496 (defn plot-results [d]497 (let [ans (analyze d)]498 (view (doto (xy-plot (:x ans) (:y ans))499 (set-title (:name d))500 (add-lines (:x ans) (:fitted ans))))501 ans))503 (defn zzz [d [A B]]504 (let [gar (vec (map (partial ideal-dna-fraction [A B]) (:temp d)))]505 (view (doto (xy-plot (:temp d) (:glow d))506 (set-title (:name d))507 (add-lines (:temp d) gar)))))512 (defn index-filter [pred coll]513 (when pred514 (for [[idx elt] (indexed coll) :when (pred elt)] idx)))519 ;; we're going to estimate two correction factors,520 ;; a constant capacative temperature delay,521 ;; and a linear decrease in brightness. We'll do this522 ;; before unit-transforms.524 (defn zipmap-collect525 "Returns a map with the keys mapped to the corresponding vals.526 adds extra values to a list"527 [keys vals]528 (loop [map {}529 ks (seq keys)530 vs (seq vals)]531 (if (and ks vs)532 (recur (if (contains? map (first ks))533 (assoc map (first ks) (cons (first vs) (map (first ks))))534 (assoc map (first ks) (list (first vs))))535 (next ks)536 (next vs))537 map)))540 (defn little-process [thermal-cap bleaching #^dna-data d]541 ((partial thermal-delay-correction thermal-cap)542 ((partial bleaching-correction bleaching) d)))544 (def little-process (memoize little-process))546 ;(defn lookup-map [#^dna-data d]549 (defn converge-function550 "this is the vertical discrepancy after applying the two transforms"551 [#^dna-data d [thermal-cap bleaching] x]552 (let [new-d (little-process thermal-cap bleaching d)553 spreads554 (map (vec (:glow new-d))555 (index-filter (partial = x) (vec (:temp new-d))))556 spread (- (apply max spreads) (apply min spreads))]557 spread))568 (defn blah [k] (comp569 ( partial newton-temp-correction3* 280 k ) temp-unit-transform first-pass))571 ;(def ggg (comp572 ; dna-melting ( partial thermal-delay-correction* 120 ) (blah 0.0018)))578 ;; Ensure that the melting function is uniquely valued by579 ;; combining samples with identical temperature values.580 (defn cooling-function581 "just put it in a map for this!"582 [source]583 (let [data (cooling-phase source)584 lookup (apply sorted-map585 (interleave586 (:temperature data) (:dna-fraction data)))]587 {:temperature (vec (keys lookup))588 :dna-fraction (vec (map lookup (keys lookup)))}))591 (defn turn [n]592 (format "%5.2f" n))594 (defn bleach-correction-2 [bleaching-constant #^dna-data d]595 (assert (= (:glow-units d) "Raw Glow (Volts)"))596 (let [old-glow (vec (:glow d))597 integral-old-glow (vec (reductions + old-glow))598 correction (fn [t] (+599 (old-glow t)600 (* bleaching-constant (integral-old-glow t))))601 new-glow (map + (map correction (range 0 (count old-glow))) old-glow)]602 ;;glow is related to the number of particles,603 ;;and the number destroyed is some fraction of604 ;;the number present and glowing.605 (assoc d606 :name (str (:name d) " |bleaching-corrected constant = " (turn bleaching-constant) "| ")607 :glow new-glow)))611 (defn ultimate-correction612 ([k-block-sample k-sample-air initial-sample-temp room-temp bleach-constant613 #^dna-data d614 ]615 ((comp616 (partial newton-temp-correction4*617 k-block-sample k-sample-air initial-sample-temp room-temp)619 temp-unit-transform620 (partial bleach-correction-2 bleach-constant)621 low-pass-correction) d))623 ([{:keys [test-k-sample-air624 test-k-block-sample625 test-sample-temp626 test-room-temp627 test-bleach]}628 #^dna-data d]629 (ultimate-correction630 (mean test-k-block-sample) (mean test-k-sample-air)631 (mean test-sample-temp) (mean test-room-temp) (mean test-bleach) d)))634 ;;((uui 0.0020 0.0001 280 293) (bleach-correction-2 1.1e-5 ?-3))637 ;;; this is for ?-3 after 35 iterations638 (def opt {:test-k-sample-air '(9.375630358472117E-4 9.375630359053611E-4), :test-k-block-sample '(0.0010343754438043107 0.0010343754455447197), :test-room-temp '(294.9804782861611 294.98047828674316), :test-sample-temp '(293.36120605294127 293.3612060546875), :test-bleach '(1.771081481128931E-5 1.7710814863094127E-5), :align 1.5796052678842228E-4})641 ;;; C-1 after 20 iterations642 (def opt2643 {:test-k-sample-air '(9.936472587585448E-4 9.936491641998292E-4), :test-k-block-sample '(2.9390106201171873E-4 2.939580917358398E-4), :test-room-temp '(294.76531982421875 294.7653388977051), :test-sample-temp '(294.765625 294.765682220459), :test-bleach '(2.39045524597168E-5 2.3906250000000002E-5), :align 1.7562642331021098E-4})646 ;;(time (def result-?-3 (doall (take 10 (iterate (partial improve ?-3) start-values-overestimates)))))649 ;;(doall (map (comp dna-melting #(ultimate-correction % ?-3)) result-?-3))652 (defn subsample653 "subsample v every n points"654 [n v]656 (vec (map (vec v) (vec (range 0 (count (vec v)) n)))))659 (defn max-difference [v] (- (apply max v) (apply min v)))661 (defn alignment [#^dna-data d]662 (let [distribution (vec (vals663 (apply sorted-map664 (interleave (:temp d) (:glow d)))))]665 (mean (map variance (partition 10 distribution)))))667 (defn garigh [d]668 (let [distribution (vec (vals669 (apply sorted-map670 (interleave (:temp d) (:glow d)))))]671 (view (visual (vec (map max-difference (partition 100 distribution)))))))674 (defn alignment-4 [#^dna-data d]675 (let [distribution (vec (vals676 (apply sorted-map677 (interleave (:temp d) (:glow d)))))]678 (reduce + (map sq (map max-difference (partition 100 distribution))))))681 (defn alignment-2 [#^dna-data d]682 (let [distribution683 (vec684 (vals685 (apply sorted-map686 (interleave (subsample 2 (:temp d)) (subsample 2(:glow d))))))]687 (reduce + (map max-difference (partition 30 distribution)))))688 (defn alignment-3 [#^dna-data d]689 (let [distribution690 (vec691 (vals692 (apply sorted-map693 (interleave (subsample 2 (:temp d)) (subsample 2(:glow d))))))]694 (reduce max (map max-difference (partition 30 distribution)))))697 (comment698 ;; this takes a while699 (def opts (zipmap all-samples (map #(last (take 20 (iterate (partial improve %) start-values))) all-samples))))701 ;(def opts (zipmap all-samples opts-vals))703 (defn mean-map [v s]704 (map mean (map (partial vector v) s)))707 (def start-values708 {:test-k-sample-air [0.000001 0.001]709 :test-k-block-sample [0.001 0.03]710 :test-room-temp [290 300]711 :test-sample-temp [285 310]712 :test-bleach [0.00001 0.0009]})714 (def start-values-2715 {:test-k-sample-air [1e-15 0.0005]716 :test-k-block-sample [0.001 0.002]717 :test-room-temp [290 300]718 :test-sample-temp [290 300]719 :test-bleach [1e-7 0.0005]})723 (def start-values-3724 {:test-k-block-sample [0.0005 0.00125 0.002]725 :test-k-sample-air [0.0000001 0.000001 0.0000019]726 :test-sample-temp [280 300]727 :test-room-temp [300 306]728 :test-bleach [0.000001 0.00001]})730 (defn condense [[a b :as v]]731 (if (< (/ (abs (- (apply max v) (apply min v))) (apply max v)) 1e-2) (vector (mean v)) v))733 (defn mass-shift734 [value v]735 (let [frac 2/3]736 (cond (>= (count v) 2)737 (let [[a b] v]738 (condense (vec (map #(float (+ (* frac %) (* (- 1 frac) value))) v))))739 (= (count v) 1)740 v)))743 (defn improve* [#^dna-data d744 {:keys [test-k-sample-air745 test-k-block-sample746 test-room-temp747 test-sample-temp748 test-bleach] :as domain}]749 (do (print \newline)750 (reduce (fn [m1 m2] (if (< (:align m1) (:align m2)) m1 m2))753 (for [k-sample-air (condense test-k-sample-air)754 k-block-sample (condense test-k-block-sample)755 room-temp (condense test-room-temp)756 initial-sample-temp (condense test-sample-temp)757 bleach-constant (condense test-bleach)]759 (do760 (print ".")761 (let [align762 (alignment-2763 (ultimate-correction764 k-block-sample k-sample-air initial-sample-temp room-temp765 bleach-constant d))766 align (if (Double/isNaN align) Double/POSITIVE_INFINITY align)]767 {:test-k-sample-air (mass-shift k-sample-air test-k-sample-air)768 :test-k-block-sample(mass-shift k-block-sample test-k-block-sample)769 :test-room-temp (mass-shift room-temp test-room-temp)770 :test-sample-temp (mass-shift initial-sample-temp test-sample-temp)771 :test-bleach (mass-shift bleach-constant test-bleach)772 :align align}))))))776 (def println-repl (bound-fn [& args] (apply println args)))777 (def print-repl (bound-fn [& args] (apply print args)))781 (defn improve [#^dna-data d782 {:keys [test-k-block-sample783 test-k-sample-air784 test-sample-temp785 test-room-temp786 test-bleach] :as domain}]787 (reduce788 (fn [m1 m2] (if (< (:align m1) (:align m2)) m1 m2))789 (let [return-hash790 (fn791 [[k-block-sample k-sample-air initial-sample-temp792 room-temp bleach-constant]]793 (do794 (print-repl ".")795 (let [align796 (alignment-4797 (ultimate-correction798 k-block-sample k-sample-air initial-sample-temp room-temp799 bleach-constant d))800 align (if (Double/isNaN align) Double/POSITIVE_INFINITY align)]801 {:test-k-sample-air (mass-shift k-sample-air test-k-sample-air)802 :test-k-block-sample(mass-shift k-block-sample test-k-block-sample)803 :test-room-temp (mass-shift room-temp test-room-temp)804 :test-sample-temp (mass-shift initial-sample-temp test-sample-temp)805 :test-bleach (mass-shift bleach-constant test-bleach)806 :align align})))]807 (pmap return-hash808 (cartesian-product809 test-k-block-sample810 test-k-sample-air811 test-sample-temp812 test-room-temp813 test-bleach)))))815 (def improve (memoize improve))817 (defn iterate-test [n #^dna-data d]818 (last (take n (iterate (partial improve d) start-values-3))))821 (defn nested-vals [key coll]822 (for [x (tree-seq coll? seq coll) :when (contains? x key)]823 (get x key)))826 (defn quantum-efficiency* [q-constant #^dna-data d]827 ;; 0.8 at room temperature828 ;; quantum efficiency is somehow829 ;; inversely proportional to temperature830 (let [correction834 (fn [t g] (/ g (* 0.8 (exp (* q-constant (- 292 t))))))]835 (assoc d836 :name (str (:name d) " |quantum-correction| ")837 :glow (map correction (:temp d) (:glow d)))))839 (def quantum-efficiency (partial quantum-efficiency* 1.2e-2))841 (defn exp-decay [[A] x]842 (* 0.8 (exp (* A (- 298 x)))))844 ;(defn final-join [#^dna-data d]848 (def join-opts849 {850 A-1 {:test-k-sample-air [1.760184242508937E-6], :test-k-block-sample [0.0012930832259977858], :test-room-temp [304.41977945963544], :test-sample-temp [281.31689453125], :test-bleach [9.956068424799014E-6], :align 0.800815268639094}851 A-2 {:test-k-sample-air [3.017639376897326E-7], :test-k-block-sample [0.0011550507430608075], :test-room-temp [304.6666717529297], :test-sample-temp [282.6337890625], :test-bleach [9.5610075732111E-6], :align 0.8530570499185829}852 A-3 {:test-k-sample-air [2.6829059556281816E-6], :test-k-block-sample [0.002413294818252325], :test-room-temp [304.6666717529297], :test-sample-temp [281.31689453125], :test-bleach [9.965317076421343E-6]}854 B-2 {:test-k-sample-air [1.6274943088016396E-6], :test-k-block-sample [0.0013714926317334175], :test-room-temp [304.6666717529297], :test-sample-temp [281.31689453125], :test-bleach [9.965317076421343E-6], :align 0.7631166194402621}855 B-3856 {:test-k-sample-air [1.455345833771086E-6], :test-k-block-sample [0.0014841814991086721], :test-room-temp [304.6666717529297], :test-sample-temp [287.9835662841797], :test-bleach [9.965317076421343E-6], :align 0.5358800697386289}858 C-1859 {:test-k-sample-air [1.6907095717518434E-6], :test-k-block-sample [0.001278722076676786], :test-room-temp [304.6666717529297], :test-sample-temp [281.31689453125], :test-bleach [9.965317076421343E-6], :align 0.7249279378017799}860 C-2861 {:test-k-sample-air [1.77524979487013E-6], :test-k-block-sample [0.001278722076676786], :test-room-temp [304.6666717529297], :test-sample-temp [281.31689453125], :test-bleach [9.965317076421343E-6], :align 2.0474987460209793}862 C-3863 {:test-k-sample-air [1.010541116860016E-6], :test-k-block-sample [0.001601272417853276], :test-room-temp [304.6666717529297], :test-sample-temp [281.31689453125], :test-bleach [9.965317076421343E-6], :align 0.7191738524207253}865 ?-1866 {:test-k-sample-air [1.5533593114014366E-6], :test-k-block-sample [0.0013761443551629782], :test-room-temp [304.6666717529297], :test-sample-temp [281.31689453125], :test-bleach [9.965317076421343E-6], :align 1.3838506291264723}867 ?-3868 {:test-k-sample-air [2.940294715851148E-7], :test-k-block-sample [0.0018434864080821474], :test-room-temp [304.6666717529297], :test-sample-temp [281.31689453125], :test-bleach [9.965317076421343E-6], :align 0.48549623932134006}870 })873 (defn final-join [#^dna-data d]875 (let [876 m (apply sorted-map (interleave (:temp d) (:glow d)))877 distribution (vec (vals m))878 ordinates (vec (keys m))879 ]880 (assoc d881 :name (str (:name d) " |joined| ")882 :temp (map (fn [region] (mean [(apply min region) (apply max region)]))883 (partition 30 ordinates))885 :glow (map (fn [region] (mean [(apply min region) (apply max region)]))886 (partition 30 distribution)))))889 (defn melting-point [#^dna-data d]890 (let [t (drop 150 (:temp d))891 g (drop 150 (:glow d))]892 (nth t (find-min (map / (diff g) (diff t) )))))895 (def target-dir (file-str "/home/r/MIT/6/6.122/DNA/output"))897 (defn x-form-dna [#^dna-data d]898 (final-join (ultimate-correction (join-opts d) d)))900 (defn save-raw-dna-curve [#^dna-data d]901 (save (dna-melting d) (str target-dir File/separator (:name d) ".png")))903 (defn save-dna-curve-with-temp [#^dna-data d*]904 (let [906 melt (melting-point d*)907 d (assoc d* :name (str (:name d*) " |M.P. = " (turn melt) " |"))908 ]909 (save (add-lines (dna-melting d) (repeat (count (:glow d)) melt) (:glow d))910 (str target-dir File/separator (:name d) ".png"))))914 (defn process-all []915 (doall (pmap save-dna-curve all-samples))916 (doall (pmap (comp save-dna-curve-with-temp x-form-dna) all-samples)))919 (def ?-temps (vec (map (comp melting-point x-form-dna) [?-1 ?-3])))920 (def A-temps (vec (map (comp melting-point x-form-dna) [A-1 A-2 A-3])))921 (def B-temps (vec (map (comp melting-point x-form-dna) [B-2 B-3])))922 (def C-temps (vec (map (comp melting-point x-form-dna) [C-1 C-2 C-3])))924 (defn report [temps]926 (sorted-map :data temps :std (sqrt (variance temps)) :mean (mean temps)))929 ;;; now it's time to start data reporting931 ;(defn process [#^dna-data d]932 ; (ultimate-correction (opts d) d)936 (report A-temps)937 {:data [348.8771481779248 349.3989434763391 348.76079920968573],938 :mean 349.0122969546499,939 :std 0.33986161910548834}941 (report B-temps)942 {:data [349.0655539116902 349.92155530431506],943 :mean 349.4935546080026,944 :std 0.6052843894485812}946 (report C-temps)947 {:data [349.92341967511976 349.68832687337056 348.2872189461977],948 :mean 349.299655164896,949 :std 0.884639745344559}951 (report ?-temps)952 {:data [350.4525305192239 349.87377093318975],953 :mean 350.1631507262068,954 :std 0.4092448279511269}