odd list behaviour

Anything that doesn't fit elsewhere.
Post Reply
ubartsch
Posts: 34
Joined: Thu May 19, 2005 11:02 am
Location: CTCN, University of Plymouth
Contact:

odd list behaviour

Post by ubartsch »

Hi,
I have a strange problem with saving Vectors to Lists.

I have writtten a piece of hoc iterates through different positions on a detailed morphological model's dendrite to inject current pulses through an iClamp.
The idea is to run t he same cell with only one IClamp at a time recording the result into a vector and collecting vectors into a List, as done many times before.

The essential code looks like this:

Code: Select all


proc injectstimrun() {local i 
	
	forsec injsec{
			
			p= secx.x[ind0]
			secname() stim0=new IClamp(p)
			stim0.del=0
			stim0.dur=600
			stim0.amp=0.005
						
			V2=new Vector()
			print V2
			secname() V2.record(&v(p),T)
                        vlist2.append(V2)
						
						
			// init  & run & plot
			
			init()
			run()

			V2.line(g2,T,1,2)
							
			V3=vlist2.o(vlist2.count()-1)
			V3.line(g2,T,2,0.1)
			
			stim0=nil
			
	}
	
	print "\n \n"
	
}

This works fine, both the original vector and the retrived vector overlay in the plot. But now the funny bit starts, in a separate proc I want to save the results to a file and then the data in the retrieved vectors is different!
Although vector id's seem to be the same?!

Code: Select all


proc save(){

		vc=vlist2.count()
		
		Res= new Matrix (n,vc+1)
		Res.setcol(0,T)
		for k=0, vc-1 {
			Res.setcol(k+1,vlist2.object[k])
			V3=vlist2.object[k]
			print V3
			V3.line(g2,T,3,0.5)}
		
		fo=new File()
		strdef fn
		sprint(fn,"%spas_serial_0%d0%d.dat",pat,passflag,i)
		fo.wopen(fn)
		tmp=Res.fprint(0, fo, "%-f\t", "\n")
		fo.close()
	
	print "     ", vc, "+1"
}
The plot of V3 in the graph is completely different to the previous 2 plots.
But the object id's of the Vecors are the same (print V3)
The relevant toplevel bit looks like this:

Code: Select all

...
print "\n   > inject stimulus & init & run \n"
injectstimrun(0)

print "\n   > save \n"
save()
...

So there isnt much happening in between. I can't figure out where the bug is. Any help is very much appreciated!

Thanks
ub
ted
Site Admin
Posts: 6303
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Post by ted »

If your message contains an accurate reproduction of proc save(), the cause of problem
may be just a common typographical error--objects in a list are retrieved as

Code: Select all

listname.object(i) // parens good
not

Code: Select all

listname.object[i] // square brackets bad
That's the kind of thing that one can look at all day long and never see. But I would have
expected an error message to be printed. so maybe I missed something.


Now some minor comments--

In proc injectstimrun(), in

Code: Select all

			secname() stim0=new IClamp(p)
 . . .
			secname() V2.record(&v(p),T)
the secname() calls won't do anything useful. Besides, they're completely unnecessary--
the
forsec seclistname { . . . }
not only iterates over each section in seclistname, but also makes that section the
"default currently accessed section" for all statements inside the curly brackets.

Instead of creating a new IClamp and asserting its parameters for each new location,
you could just create it once outside the forsec loop, then take advantage of the fact that
every point process has a loc function that can be used to specify where it is located--
see
https://www.neuron.yale.edu/phpBB2/view ... 7613154b24
for an example. Would save a bit of time and garbage cleanup. proc injectstimrun()
would then start with

Code: Select all

proc injectstimrun() {local i 
	stim0=new IClamp(0.5) // attach to middle of default section
	stim0.del=0
	stim0.dur=600
	stim0.amp=0.005
	
	forsec injsec{
			p= secx.x[ind0]
			stim0.loc(p)

			V2=new Vector()
			 . . .
and the
stim0=nil
can also be omitted.

There's no need to do
init()
run()
because run() itself calls init().
ubartsch
Posts: 34
Joined: Thu May 19, 2005 11:02 am
Location: CTCN, University of Plymouth
Contact:

Post by ubartsch »

Hi Ted,
Many thanks for the help, the improvemnts make sense, didnt know one could use loc for any point process, not just Impedance. Why is that not in the programmers reference?

Unfortuntely the problem persists even after having made the suggested modifications. Apparently squared brackets work fine on any List? At least in a little test on the command line.

I'm sorry, I guess there must be a very simple typo or something?!
Just can't find it....

Thanks for having another look!
ub

The code looks like this (exactly like I run it):

Code: Select all


objref indtime, nil, V2, g2, Vslist, Vlist2, V3, V4
indtime=new Vector()
V3= new Vector()
g2=new Graph(0)
//g2.size(0,1000,-70,-65)
g2.view(0,-70,1000,3,   0,100,400,200)

Vslist = new List()
Vlist2 = new List()

proc injectstimrun() {local i 
	i=$1
	sh.view(-300,-300,900,1000,  420,100,300,300)
	
	ind0=0
	stim0=new IClamp(.5)
	stim0.del=0
	stim0.dur=600
	stim0.amp=0.005

	forsec injsec{
			print secname()
			//print unisec[i].x[ind1]
			//sref= new SectionRef()
			p= secx.x[ind0]
			//d=distance(p)	
			//stimlist.append(stim0)
			stim0.loc(p)

			V2=new Vector()
			print V2
			V2.record(&v(p),T)
			Vlist2.append(V2)
			
			V=new Vector()
			V.record(&PC[0].soma.v(.5),T)
			Vslist.append(V)
			
			// init  & run
			run()
			
			V2.line(g2,T,1,2)
			V.line(g2,T,4,0.1)
			sh.point_mark(stim0,3)
						
			V3=Vlist2.o(Vlist2.count()-1)
			V3.line(g2,T,2,0.1)
			
			//stim0=nil
			
			ind0=ind0+1
	}
	
	print "\n \n"
	
}

....

proc save(){
	
		
		vc=Vlist2.count()
		
		Res= new Matrix (n,vc+1)
		Res.setcol(0,T)
		for k=0, vc-1 {
			Res.setcol(k+1,Vlist2.o(k))
			V4=Vlist2.o(k)
			print V4
			V4.line(g2,T,3,0.5)
			}
		
		fo=new File()
		strdef fn
		sprint(fn,"%spas_serial_0%d0%d.dat",pat,passflag,i)
		fo.wopen(fn)
		tmp=Res.fprint(0, fo, "%-f\t", "\n")
		fo.close()
	
	print "     ", vc, "+1"
}
ubartsch
Posts: 34
Joined: Thu May 19, 2005 11:02 am
Location: CTCN, University of Plymouth
Contact:

Post by ubartsch »

a little remark,
same thing happens when i use an array for collecting vectors.
so it's not a list problem.
is there any way that the data in the vectors could have been altered "accidentally"?
why are the id's still the same?

or maybe the graph is not showing the correct data ?

ub
ubartsch
Posts: 34
Joined: Thu May 19, 2005 11:02 am
Location: CTCN, University of Plymouth
Contact:

Post by ubartsch »

getting further...
as soon as i leave the forsec injsec loop, the absolute object id's reference to different data.

line A gives me a perfect match with the graph in injectstimrun(), whereas line B matches with teh result in the save() proc.

is there any way that forsec can alter the object id's?
and where does the data come from anyway?

cheers
ub


Code: Select all

proc injectstimrun() {local i 
         forsec injsec{
                        ....
			Vector[ind0+190].line(g2,T,4,7) // line A
			ind0=ind0+1
			
	}
	Vector[190].line(g2,T,5,7) // line B
	print "\n \n"
	
}
[/code]
ubartsch
Posts: 34
Joined: Thu May 19, 2005 11:02 am
Location: CTCN, University of Plymouth
Contact:

Post by ubartsch »

hi,
problem solved:
a simple copying of the vector used for recording into a new vector works.]
something like:

Code: Select all

V2=new  Vector()
forsec injsec{
V2.record(&v(p),T)
run()
V3 = new Vector()
V3.copy(V2)
Vlist2.append(V3)
}
gives the real data!

it seems the critical mistake was to create a new Vector for each run of the forsec loop, hence the vectors to which i recorded were not destroyed but continued to record in every run, so that at the end i was seeing the results of the last run in my save proc.
well, another lesson learned... but maybe this helps anyone to avoid a similar mistake?!

cheers
ullrich
ted
Site Admin
Posts: 6303
Joined: Wed May 18, 2005 4:50 pm
Location: Yale University School of Medicine
Contact:

Post by ted »

Right. hoc destroys an object when its reference count falls to 0, but appending an objref
to a list increases the underlying object's reference count by 1, so the object will continue
to exist even if the link between the objref and the object is broken. Example:

Code: Select all

oc>objref foo
oc>foo = new Vector()
oc>foo
        Vector[3]
hoc tells us that Vector[3] is the object to which objref foo refers. Since we just created
Vector[3], its reference count is 1, and we could kill it by simply executing
objref foo

But if we first append foo to a list, we increase Vector[3]'s reference count to 2.

Code: Select all

oc>objref mylist
oc>mylist = new List()
oc>mylist.append(foo)
        1 
(an aside: the 1 merely tells us how many objects are in mylist)

Now let's try to kill Vector[3] by executing objref foo--

Code: Select all

oc>objref foo
oc>foo
        NULLobject 
as expected. But is there still a Vector[3]?

Code: Select all

oc>mylist.o(0)
        Vector[3] 
oc>
So Vector[3] still lives. And if
foo.record(&varname . . . )
had been executed, Vector[3] would continue to capture a fresh recording of varname
on every new simulation run.
Post Reply