See my variant of your application:
https://gist.github.com/efdb66487e899446332f
I don't know if it works, because I can't test :(

My thoughts about your example
You shouldn't think about this procedure as about procedure where you use
loop, like in other imperative languages with mutable data. As I understand
you tried something like:

for every line in file do
    if line matches then
         convert line to coords
         add coords to global variable hold-coords
   end if
end for

But it's not the clojure way, I think clojure way is:

get all lines as sequence
convert every element of this sequence to vector of coords
concat all vectors to one


And in your example
>dpa> (def y  [5 6 7]) (let [x (into y [2 3 4]) y x ] y)
>[5 6 7 2 3 4]
>dpa> y
>[5 6 7]
When you use y in let, it introduce new local variable y, which "hides"
global y
It you want to use mutable data (I don't think it's good), you can use atoms
- it's special mmm... mechanism for mutable data:

user> (def y (atom [1 2 3]))
#'user/y

user> @y
[1 2
3]

user> (swap! y into [4 5 6])
[1 2 3 4 5
6]

user> @y
[1 2 3 4 5
6]


Here you bind to variable y an atom with initial value - vector [1 2 3]. To
get value of atom you use @ before the variable name: @y
To change value you call (swap! atom func x y z). First it calculates new
value like this: (func @atom x y z), in our example it will calculate (into
@y [4 5 6]). It returns vector [1 2 3 4 5 6], and this vector is set as new
value of y.

Regards,
Nikita Beloglazov


On Thu, Aug 5, 2010 at 11:49 PM, Dave <david.dreisigme...@gmail.com> wrote:

> Thanks for the extra parentheses catch.  I just noticed that while
> working on a different function (after hours of trying to figure it
> out).
>
> The program is reading in a pdb file line-by-line.  I only want the
> xyz-coordinates of carbon atoms, avoiding any repeats when the
> coordinate of an atom is uncertain.  Also, a protein may have multiple
> sub-units, and the chains parameter can pick out the desired sub-
> unit(s).  So I need to:
> 1) make sure the line is long enough
> 2) make sure I have an atom
> 3) make sure it's not a repeated measurement
> 4) make sure it's a C_{alpha} atom
> If the current pdb-file line matches those criteria, I'll then put its
> xyz-coordinates into the output matrix.
>
> I tried this using let:
>
> (defn process-dpa-file2
>   "This makes the matrix of CA coordinates from a pdb file."
>  [pdb-file chains]
>  (def hold-coords [])
>  (doseq [^String line (read-lines pdb-file)]
>    ;; Make sure the file line is the correct length
>    ;; We only want the atom entries
>    ;; We don't want any repeated measurements for an atom
>    ;; Is it a CA?
>    ;; Are we using this chain?
>    (if (and (= (.length line) 80)
>             (= (str (.substring line 0 4) (.substring line 26 27)
> (.substring line 13 15)) "ATOM CA")
>             (substring? (.substring line 21 22) chains))
>       ;; These are the CA coordinates
>      (let [coords (into hold-coords [ (Double. (.substring line 30
> 37))
>                                        (Double. (.substring line 38 45))
>                                        (Double. (.substring line 46 53))])
>             hold-coords coords]))
>    (matrix hold-coords 3)))
>
> but the output gives:
>
> dpa> (def my-mat (process-dpa-file2 "/Users/daviddreisigmeyer/MyStuff/
> DPA_release_12-JUL-2010/1RD8.pdb" "A") )
> #'dpa/my-mat
> dpa> my-mat
> nil
>
> A simpler example:
>
> dpa> (def y  [5 6 7]) (let [x (into y [2 3 4]) y x ] y)
> [5 6 7 2 3 4]
> dpa> y
> [5 6 7]
>
> So it seems that in process-dpa-file2 I have the coordinates of the
> 1st carbon atom in hold-coords, and then the 2nd, the 3rd ... After
> finding the 3rd carbon, I'd want:
>
> hold-coords = [x1 y1 z1 x2 y2 z2 x3 y3 z3] (**)
>
> but instead I get
>
> hold-coords = [x3 y3 z3].  Any idea about how I could get (**)
> instead?  Thanks! -Dave
>
> On Aug 5, 2:46 pm, Nikita Beloglazov <nikelandj...@gmail.com> wrote:
> > Hi, Dave
> > Why do you use 2 parenthesis before "with-open" in the first variant?
> > And, as I know, it's not good practice to use def inside functions. Use
> let
> > instead.
> > I also advice you to split your program to smaller functions.
> > Can you describe, what your program must do? Because don't understand :(
> >
> >
> >
> > On Thu, Aug 5, 2010 at 9:28 PM, Dave <david.dreisigme...@gmail.com>
> wrote:
> > > Hi,
> >
> > > I don't understand why this doesn't work:
> >
> > > (ns dpa
> > >  (:gen-class)
> > >  (:use [incanter.core :only ( matrix )]
> > >        [clojure.core :only ( defn doseq line-seq println with-open )]
> > >        [clojure.contrib.string :only ( blank? substring? )]
> > >  (:import (java.io BufferedReader FileReader)))
> >
> > > (defn process-dpa-file
> > >  "This makes the matrix of CA coordinates from a pdb file."
> > >  [pdb-file chains]
> > >  (def hold-coords [])
> > >  ((with-open [rdr (BufferedReader. (FileReader. pdb-file))]
> > >      (doseq [^String line (line-seq rdr)]
> > >    ;; Make sure the file line is the correct length
> > >    ;; We only want the atom entries
> > >    ;; We don't want any repeated measurements for an atom
> > >    ;; Is it a CA?
> > >    ;; Are we using this chain?
> > >    (if (and (= (.length line) 80)
> > >             (= (str (.substring line 0 4) (.substring line 26 27)
> > > (.substring line 13 15)) "ATOM CA")
> > >             (substring? (.substring line 21 22) chains))
> > >      ;; This are the CA coordinates
> > >      (def hold-coords (into hold-coords [ (Double. (.substring line
> > > 30 37))
> > >                                           (Double. (.substring line 38
> 45))
> > >                                           (Double. (.substring line 46
> 53))
> > > ] )))))
> > >   (matrix hold-coords 3)))
> >
> > > dpa> (def my-mat (process-dpa-file "/Users/daviddreisigmeyer/MyStuff/
> > > DPA_release_12-JUL-2010/1RD8.pdb" "A") )
> > > No message.
> > >  [Thrown class java.lang.NullPointerException]
> >
> > > Restarts:
> > >  0: [QUIT] Quit to the SLIME top level
> >
> > > Backtrace:
> > >  0: dpa$process_dpa_file.invoke(NO_SOURCE_FILE:1)
> > >  1: clojure.lang.AFn.applyToHelper(AFn.java:165)
> > >  2: clojure.lang.AFn.applyTo(AFn.java:151)
> > >  3: clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:2901)
> > >  4: clojure.lang.Compiler$DefExpr.eval(Compiler.java:361)
> > >  5: clojure.lang.Compiler.eval(Compiler.java:5424)
> > >  6: clojure.lang.Compiler.eval(Compiler.java:5386)
> > >  7: clojure.core$eval.invoke(core.clj:2382)
> > >  8: swank.commands.basic$eval_region.invoke(basic.clj:47)
> > >  9: swank.commands.basic$eval_region.invoke(basic.clj:37)
> > >  10: swank.commands.basic$eval799$listener_eval__800.invoke(basic.clj:
> > > 71)
> > >  11: clojure.lang.Var.invoke(Var.java:365)
> > >  12: dpa$eval9236.invoke(NO_SOURCE_FILE)
> > >  13: clojure.lang.Compiler.eval(Compiler.java:5419)
> > >  14: clojure.lang.Compiler.eval(Compiler.java:5386)
> > >  15: clojure.core$eval.invoke(core.clj:2382)
> > >  16: swank.core$eval_in_emacs_package.invoke(core.clj:90)
> > >  17: swank.core$eval_for_emacs.invoke(core.clj:237)
> > >  18: clojure.lang.Var.invoke(Var.java:373)
> > >  19: clojure.lang.AFn.applyToHelper(AFn.java:169)
> > >  20: clojure.lang.Var.applyTo(Var.java:482)
> > >  21: clojure.core$apply.invoke(core.clj:540)
> > >  22: swank.core$eval_from_control.invoke(core.clj:97)
> > >  23: swank.core$eval_loop.invoke(core.clj:102)
> > >  24: swank.core$spawn_repl_thread$fn__484$fn__485.invoke(core.clj:307)
> > >  25: clojure.lang.AFn.applyToHelper(AFn.java:159)
> > >  26: clojure.lang.AFn.applyTo(AFn.java:151)
> > >  27: clojure.core$apply.invoke(core.clj:540)
> > >  28: swank.core$spawn_repl_thread$fn__484.doInvoke(core.clj:304)
> > >  29: clojure.lang.RestFn.invoke(RestFn.java:398)
> > >  30: clojure.lang.AFn.run(AFn.java:24)
> > >  31: java.lang.Thread.run(Thread.java:637)
> >
> > > But, this does work:
> >
> > > (defn process-dpa-file
> > >  "This makes the matrix of CA coordinates from a pdb file."
> > >  [pdb-file chains]
> > >  (def hold-coords [])
> > >  (doseq [^String line (read-lines pdb-file)]
> > >    ;; Make sure the file line is the correct length
> > >    ;; We only want the atom entries
> > >    ;; We don't want any repeated measurements for an atom
> > >    ;; Is it a CA?
> > >    ;; Are we using this chain?
> > >    (if (and (= (.length line) 80)
> > >             (= (str (.substring line 0 4) (.substring line 26 27)
> > > (.substring line 13 15)) "ATOM CA")
> > >             (substring? (.substring line 21 22) chains))
> > >      ;; This are the CA coordinates
> > >      (def hold-coords (into hold-coords [ (Double. (.substring line
> > > 30 37))
> > >                                           (Double. (.substring line 38
> 45))
> > >                                           (Double. (.substring line 46
> 53))
> > > ] ))))
> > >  (matrix hold-coords 3))
> >
> > > dpa> (def my-mat (process-dpa-file "/Users/daviddreisigmeyer/MyStuff/
> > > DPA_release_12-JUL-2010/1RD8.pdb" "A") )
> > > #'dpa/my-mat
> >
> > > I'd certainly appreciate any comments on the code in general.  I only
> > > have a Matlab/R/Fortran 95 background.
> >
> > > Thanks,
> >
> > > -Dave
> >
> > > --
> > > You received this message because you are subscribed to the Google
> > > Groups "Clojure" group.
> > > To post to this group, send email to clojure@googlegroups.com
> > > Note that posts from new members are moderated - please be patient with
> > > your first post.
> > > To unsubscribe from this group, send email to
> > > clojure+unsubscr...@googlegroups.com<clojure%2bunsubscr...@googlegroups.com>
> <clojure%2bunsubscr...@googlegroups.com<clojure%252bunsubscr...@googlegroups.com>>
> > > For more options, visit this group at
> > >http://groups.google.com/group/clojure?hl=en
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com<clojure%2bunsubscr...@googlegroups.com>
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to