file:/local_home/local_home/hugo/neurospaces_project/heccer/source/c/snapshots/0/integrators/heccer/neurospaces/segments.c (Thu Jul 24 21:27:33 2008
) HOME
1: //
2: // Heccer : a compartmental solver that implements efficient Crank-Nicolson
3: // integration for neuronal models.
4: //
5:
6: //////////////////////////////////////////////////////////////////////////////
7: //'
8: //' Heccer : testbed C implementation
9: //'
10: //' Copyright (C) 2006-2008 Hugo Cornelis
11: //'
12: //' functional ideas .. Hugo Cornelis, hugo.cornelis@gmail.com
13: //'
14: //' coding ............ Hugo Cornelis, hugo.cornelis@gmail.com
15: //'
16: //////////////////////////////////////////////////////////////////////////////
17:
18:
19: #include <stdio.h>
20: #include <stdlib.h>
21:
22: #include <neurospaces/pidinstack.h>
23: #include <neurospaces/treespacetraversal.h>
24:
25: #include "heccer/addressing.h"
26: #include "heccer/compartment.h"
27: #include "heccer/intermediary.h"
28: #include "heccer/neurospaces/heccer.h"
29: #include "heccer/neurospaces/segments.h"
30: #include "heccer/service.h"
31:
32:
33: static
34: int
35: solver_segmentprocessor(struct TreespaceTraversal *ptstr, void *pvUserdata);
36:
37: static int cellsolver_getsegments(struct Heccer *pheccer, struct TranslationService *pts);
38:
39: static int cellsolver_linksegments(struct Heccer *pheccer);
40:
41: static int cellsolver_setupcomp2mech(struct Heccer *pheccer);
42:
43:
44: static
45: int
46: solver_segmentprocessor(struct TreespaceTraversal *ptstr, void *pvUserdata)
47: {
48: //- set default result : ok
49:
50: int iResult = TSTR_PROCESSOR_SUCCESS;
51:
52: //- get actual symbol
53:
54: struct symtab_HSolveListElement *phsle = (struct symtab_HSolveListElement *)TstrGetActual(ptstr);
55:
56: //- if segment
57:
58: if (instanceof_segment(phsle))
59: {
60: //- get pointer to intermediary
61:
62: struct Heccer *pheccer = (struct Heccer *)pvUserdata;
63:
64: struct Intermediary *pinter = &pheccer->inter;
65:
66: //- register current symbol
67:
68: int iSegment = pinter->iCompartments;
69:
70: //- register type
71:
72: pinter->pcomp[iSegment].mc.iType = MATH_TYPE_Compartment;
73:
74: //- register identification
75:
76: //! note: assumes pp define HECCER_SOURCE_NEUROSPACES
77:
78: int iSerial = PidinStackToSerial(ptstr->ppist);
79:
80: iSerial = ADDRESSING_NEUROSPACES_2_HECCER(iSerial);
81:
82: pinter->pcomp[iSegment].mc.iSerial = iSerial;
83:
84: #ifdef HECCER_SOURCE_TYPING
85:
86: int iModelSourceType
87: = SymbolParameterResolveValue(phsle, ptstr->ppist, "SOURCE_TYPE");
88:
89: pinter->pcomp[iSegment].mc.iModelSourceType = iModelSourceType;
90:
91: #endif
92:
93: //- register parameters
94:
95: //t check for error returns, abort traversal if necessary
96:
97: double dCm
98: = SymbolParameterResolveScaledValue(phsle, ptstr->ppist, "CM");
99:
100: if (dCm == FLT_MAX)
101: {
102: iResult = TSTR_PROCESSOR_ABORT;
103: }
104:
105: double dEm
106: = SymbolParameterResolveValue(phsle, ptstr->ppist, "ELEAK");
107:
108: if (dEm == FLT_MAX)
109: {
110: iResult = TSTR_PROCESSOR_ABORT;
111: }
112:
113: double dInitVm
114: = SymbolParameterResolveValue(phsle, ptstr->ppist, "Vm_init");
115:
116: if (dInitVm == FLT_MAX)
117: {
118: iResult = TSTR_PROCESSOR_ABORT;
119: }
120:
121: double dInject
122: = SymbolParameterResolveValue(phsle, ptstr->ppist, "INJECT");
123:
124: if (dInject == FLT_MAX)
125: {
126: dInject = 0.0;
127: }
128:
129: double dRa
130: = SymbolParameterResolveScaledValue(phsle, ptstr->ppist, "RA");
131:
132: if (dRa == FLT_MAX)
133: {
134: iResult = TSTR_PROCESSOR_ABORT;
135: }
136:
137: double dRm
138: = SymbolParameterResolveScaledValue(phsle, ptstr->ppist, "RM");
139:
140: if (dRm == FLT_MAX)
141: {
142: iResult = TSTR_PROCESSOR_ABORT;
143: }
144:
145: pinter->pcomp[iSegment].dCm = dCm;
146: pinter->pcomp[iSegment].dEm = dEm;
147: pinter->pcomp[iSegment].dInitVm = dInitVm;
148: pinter->pcomp[iSegment].dInject = dInject;
149: pinter->pcomp[iSegment].dRa = dRa;
150: pinter->pcomp[iSegment].dRm = dRm;
151:
152: //- register serial of parent
153:
154: {
155: struct symtab_Parameters *pparParent
156: = SymbolFindParameter(phsle, ptstr->ppist, "PARENT");
157:
158: if (pparParent)
159: {
160: //t I can just subtract the cell's segment ID ?
161:
162: struct PidinStack *ppistParent
163: = ParameterResolveToPidinStack(pparParent, ptstr->ppist);
164:
165: if (ppistParent)
166: {
167: PidinStackLookupTopSymbol(ppistParent);
168:
169: int iParent = PidinStackToSerial(ppistParent);
170:
171: //t check for error
172:
173: if (iParent != INT_MAX)
174: {
175: iParent = ADDRESSING_NEUROSPACES_2_HECCER(iParent);
176:
177: pinter->pcomp[iSegment].iParent = iParent;
178: }
179: else
180: {
181: //! parent does not exist
182:
183: iResult = TSTR_PROCESSOR_ABORT;
184: }
185: }
186: else
187: {
188: iResult = TSTR_PROCESSOR_ABORT;
189: }
190: }
191: else
192: {
193: pinter->pcomp[iSegment].iParent = -1;
194: }
195: }
196:
197: //- increment number of solved segments
198:
199: pinter->iCompartments++;
200:
201: if (iResult == TSTR_PROCESSOR_ABORT)
202: {
203: HeccerError
204: (pheccer,
205: NULL,
206: "compartment array translation failed at compartment (compartment %i, serial %i)\n",
207: pinter->iCompartments,
208: pinter->pcomp[iSegment].mc.iSerial);
209: }
210:
211: }
212:
213: //- return result
214:
215: return(iResult);
216: }
217:
218:
219: static int cellsolver_getsegments(struct Heccer *pheccer, struct TranslationService *pts)
220: {
221: //- set default result : ok
222:
223: int iResult = TRUE;
224:
225: //- allocate pidin stack pointing to root
226:
227: struct PidinStack *ppistRoot = pts->ptsd->ppistRoot;
228:
229: struct symtab_HSolveListElement *phsleRoot = pts->ptsd->phsleRoot;
230:
231: //- get model context to solve
232:
233: struct PidinStack *ppistModel
234: = SymbolPrincipalSerial2Context(phsleRoot, ppistRoot, pts->ptsd->iModel);
235:
236: if (ppistModel)
237: {
238: //- lookup symbol
239:
240: struct symtab_HSolveListElement *phsleModel
241: = PidinStackLookupTopSymbol(ppistModel);
242:
243: int iSegments = SymbolCountSegments(phsleModel, ppistModel);
244:
245: if (iSegments == 0)
246: {
247: char pc[1000];
248:
249: PidinStackString(ppistModel, pc, sizeof(pc));
250:
251: HeccerError
252: (pheccer,
253: NULL,
254: "no compartments found inside %s\n",
255: pc);
256:
257: return(FALSE);
258: }
259:
260: int i;
261:
262: //- allocate intermediary for segments to solve
263:
264: struct Intermediary *pinter = &pheccer->inter;
265:
266: pinter->iCompartments = 0; //iSegments;
267:
268: pinter->pcomp
269: = (struct Compartment *)calloc(iSegments, sizeof(struct Compartment));
270:
271: //- register solved segments in cell
272:
273: if (SymbolTraverseSegments
274: (phsleModel, ppistModel, solver_segmentprocessor, NULL, pheccer) == -1)
275: {
276: iResult = FALSE;
277: }
278:
279: //t should use SolverInfoPrincipalSerial2SegmentSerial() for this
280:
281: //- link the segments together using the parent link
282:
283: iResult = iResult && cellsolver_linksegments(pheccer);
284:
285: //- produce a piC2m array: all zeros for now
286:
287: iResult = iResult && cellsolver_setupcomp2mech(pheccer);
288: }
289: else
290: {
291: iResult = FALSE;
292: }
293:
294: //- return result
295:
296: return(iResult);
297: }
298:
299:
300: static int cellsolver_linksegments(struct Heccer *pheccer)
301: {
302: //- set default result : ok
303:
304: int iResult = TRUE;
305:
306: //! this can never fail: multiple parent and multiple root
307: //! diagnosis is left to the minimum degree logic.
308:
309: //- loop over all compartments
310:
311: struct Intermediary *pinter = &pheccer->inter;
312:
313: int iCompartment;
314:
315: for (iCompartment = 0 ; iCompartment < pinter->iCompartments ; iCompartment++)
316: {
317: //- get current compartment
318:
319: struct Compartment *pcomp = &pinter->pcomp[iCompartment];
320:
321: //- get parent serial
322:
323: int iParent = pcomp->iParent;
324:
325: if (iParent != -1)
326: {
327: //- search all compartments
328:
329: int i;
330:
331: for (i = 0 ; i < pinter->iCompartments ; i++)
332: {
333: //- get current compartment
334:
335: struct Compartment *pcompParent = &pinter->pcomp[i];
336:
337: //- if is parent
338:
339: if (pcompParent->mc.iSerial == iParent)
340: {
341: //- ok, stop searching loop
342:
343: break;
344: }
345: }
346:
347: //- set current compartment parent index
348:
349: if (i < pinter->iCompartments)
350: {
351: pcomp->iParent = i;
352: }
353: else
354: {
355: HeccerError
356: (pheccer,
357: NULL,
358: "compartment (compartment %i, serial %i (internal %i)) parent linking failed for parent serial %i (internal %i)\n",
359: iCompartment,
360: ADDRESSING_HECCER_2_NEUROSPACES(pcomp->mc.iSerial),
361: pcomp->mc.iSerial,
362: ADDRESSING_HECCER_2_NEUROSPACES(iParent),
363: iParent);
364:
365: iResult = FALSE;
366: }
367: }
368: }
369:
370: //- return result
371:
372: return(iResult);
373: }
374:
375:
376: static int cellsolver_setupcomp2mech(struct Heccer *pheccer)
377: {
378: //- allocate
379:
380: struct Intermediary *pinter = &pheccer->inter;
381:
382: pinter->piC2m = (int *)calloc(pinter->iCompartments + 1, sizeof(int));
383:
384: //- sign end of array
385:
386: pinter->piC2m[pinter->iCompartments] = -1;
387:
388: //- return result
389:
390: return(pinter->piC2m != NULL);
391: }
392:
393:
394: int HeccerNeurospacesSegments2Compartments(struct TranslationService *pts)
395: {
396: //- set the service function pointer to cellsolver_getsegments()
397:
398: pts->segments_inspector = cellsolver_getsegments;
399:
400: //- return result
401:
402: return(1);
403: }
404:
405:
406:
Generated by Xrefactory version 2.0.14 on Thu Jul 24 22:41:20 2008