file:/local_home/local_home/hugo/neurospaces_project/heccer/source/c/snapshots/0/integrators/heccer/neurospaces/mechanisms.c (Thu Jul 24 21:31:03 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: #include <string.h>
22: #include <strings.h>
23:
24: #include <neurospaces/attachment.h>
25: #include <neurospaces/function.h>
26: #include <neurospaces/parsersupport.h>
27: #include <neurospaces/pidinstack.h>
28: #include <neurospaces/treespacetraversal.h>
29:
30: #include "heccer/addressing.h"
31: #include "heccer/compartment.h"
32: #include "heccer/intermediary.h"
33: #include "heccer/mathcomponent.h"
34: #include "heccer/neurospaces/heccer.h"
35: #include "heccer/neurospaces/mechanisms.h"
36: #include "heccer/service.h"
37:
38:
39: struct TableAllocatorData
40: {
41: //m symbol with value array
42:
43: struct symtab_HSolveListElement *phsle;
44:
45: //m context of the symbol
46:
47: struct PidinStack *ppist;
48: };
49:
50:
51: struct MathComponentData
52: {
53: //m solution engine
54:
55: struct Heccer *pheccer;
56:
57: //m compartment number
58:
59: int iCompartment;
60:
61: //m compartment 2 mechanism convertor
62:
63: int *piC2m;
64:
65: //m current compartment
66:
67: struct symtab_HSolveListElement *phsleCompartment;
68:
69: struct PidinStack *ppistCompartment;
70:
71: //m array of all math component types
72:
73: int iDescendants;
74:
75: int iCurrentType;
76:
77: int *piTypes;
78:
79: //m current mathcomponent
80:
81: struct MathComponent * pmc;
82:
83: //m number of spikegens
84:
85: int iSpikeGens;
86:
87: //m operational status: positive is positive, negative is negative (error)
88:
89: int iStatus;
90:
91: char pcContext[1000];
92:
93: char *pcMessage;
94:
95: //m channels that contribute to a pool
96:
97: int iConnectors;
98:
99: int **ppiConnectors;
100:
101: };
102:
103:
104: #define STATUS_OVERFLOW -1
105: #define STATUS_UNKNOWN_TYPE -2
106: #define STATUS_MANY_POOLS -3
107: #define STATUS_MEMORY -4
108: #define STATUS_CONSISTENCY -5
109: #define STATUS_UNRESOLVABLE_PARAMETERS -6
110: #define STATUS_MANY_CHANNELS -7
111: #define STATUS_UNKNOWN_ERROR -8
112: #define STATUS_NON_CHANNEL_OUTPUTS_IK -9
113: #define STATUS_CONSTANT_NERNST -10
114: #define STATUS_NON_POOL_FOR_NERNST -11
115: #define STATUS_ILLEGAL_PARAMETER_VALUES -12
116: #define STATUS_UNQUALIFIABLE_FILENAME -13
117: #define STATUS_UNKNOWN_CHANNEL_TYPE1 -14
118: #define STATUS_UNKNOWN_CHANNEL_TYPE2 -15
119: #define STATUS_UNKNOWN_CHANNEL_TYPE3 -16
120:
121: static
122: char *ppcStatusMessages[] =
123: {
124: NULL,
125: "overflow",
126: "unknown mechanism type found in the intracellular mechanisms of the model",
127: "many_pools: channels can have at most one concentration dependency",
128: "out of memory",
129: "found an internal inconsistency during typing of the model intracellular mechanisms",
130: "unresolvable parameters: the model container does not associate a numerical value with one of the parameters",
131: "many_channels: an exponential decay concentration pool had to many channel feeds (max is EXPONENTIALDECAY_CONTRIBUTORS)" ,
132: "unknown_error during channel examination",
133: "non_channel_outputs_ik: something feeds a current to a pool, but it is not a channel while it should",
134: "constant_nernst: the nerst equation must be connected to an internal concentration pool",
135: "non_pool_for_nernst: the internal concentration of a nerst equation is not connected to a concentration pool",
136: "illegal_parameter_values: some parameters have values that don't make sense from a mathematical viewpoint",
137: "unqualifiable_filename: a parameter filename cannot be resolved to an existing file",
138: "cannot determine the value of a channel type parameter",
139: "unknown_channel_type2",
140: "unknown_channel_type3",
141: NULL,
142: };
143:
144:
145: static int ConnectionSource2Target(struct MathComponentData * pmcd, struct MathComponent * pmc);
146:
147: static
148: int
149: MathComponentDataStatusSet(struct MathComponentData * pmcd, int iStatus, struct PidinStack *ppist);
150:
151: static
152: int
153: MathComponentDataTypeRegister(struct MathComponentData * pmcd, int iType, struct PidinStack *ppist);
154:
155: static
156: double
157: TableAllocatorProcessor(struct TableAllocatorData *ptd, int iValue);
158:
159: static
160: int
161: solver_channel_activation_concentration_processor(struct TreespaceTraversal *ptstr, void *pvUserdata);
162:
163: static
164: int
165: solver_channel_activation_processor(struct TreespaceTraversal *ptstr, void *pvUserdata);
166:
167: static
168: int
169: solver_channel_activation_inactivation_processor(struct TreespaceTraversal *ptstr, void *pvUserdata);
170:
171: static
172: int
173: solver_channel_persistent_steadystate_dualtau_processor(struct TreespaceTraversal *ptstr, void *pvUserdata);
174:
175: static
176: int
177: solver_channel_persistent_steadystate_tau_processor(struct TreespaceTraversal *ptstr, void *pvUserdata);
178:
179: static
180: int
181: solver_channel_springmass_processor(struct TreespaceTraversal *ptstr, void *pvUserdata);
182:
183: static
184: int
185: solver_channel_steadystate_steppedtau_processor(struct TreespaceTraversal *ptstr, void *pvUserdata);
186:
187: static
188: int
189: solver_mathcomponent_finalizer(struct TreespaceTraversal *ptstr, void *pvUserdata);
190:
191: static
192: int
193: solver_mathcomponent_processor(struct TreespaceTraversal *ptstr, void *pvUserdata);
194:
195: static int cellsolver_getmathcomponents(struct Heccer *pheccer, struct TranslationService *pts);
196:
197: static int cellsolver_linkmathcomponents(struct Heccer * pheccer, struct MathComponentData * pmcd);
198:
199: static
200: TreespaceTraversalProcessor *
201: Type2Processor(int iType);
202:
203:
204: static int ConnectionSource2Target(struct MathComponentData * pmcd, struct MathComponent * pmc)
205: {
206: //t I think this function can be removed completely, because the
207: //t connectivity can be translated directly from the model in
208: //t neurospaces, no need for this indirection.
209:
210: //- set default result : none
211:
212: int iResult = -1;
213:
214: //- loop over the contributors
215:
216: int iChannelContributors = pmcd->iConnectors;
217:
218: int **ppiChannelContributors = pmcd->ppiConnectors;
219:
220: int i;
221:
222: for (i = 0 ; i < iChannelContributors ; i++)
223: {
224: //- if found
225:
226: if (ppiChannelContributors[i][0] == pmc->iSerial)
227: {
228: //- set result
229:
230: iResult = ppiChannelContributors[i][1];
231:
232: //- break searching loop
233:
234: break;
235: }
236: }
237:
238: //- return result
239:
240: return(iResult);
241: }
242:
243:
244: static
245: int
246: MathComponentDataStatusSet(struct MathComponentData * pmcd, int iStatus, struct PidinStack *ppist)
247: {
248: //- set default result: current status
249:
250: int iResult = pmcd->iStatus;
251:
252: //- if everything still ok
253:
254: if (iResult > 0)
255: {
256: //- get string from context
257:
258: PidinStackString(ppist, pmcd->pcContext, sizeof(pmcd->pcContext));
259:
260: //- set new status
261:
262: pmcd->iStatus = iStatus;
263:
264: //- set result: new status
265:
266: iResult = pmcd->iStatus;
267: }
268:
269: //- return result
270:
271: return(iResult);
272: }
273:
274:
275: static
276: int
277: MathComponentDataTypeRegister(struct MathComponentData * pmcd, int iType, struct PidinStack *ppist)
278: {
279: //- if we were able to determine the type
280:
281: if (iType != INT_MAX)
282: {
283: //- if we were allowed to skip this component
284:
285: if (iType == -2)
286: {
287: }
288:
289: //- else
290:
291: else
292: {
293: //- if no overflow
294:
295: if (pmcd->iCurrentType < pmcd->iDescendants)
296: {
297: //- set the type in the array
298:
299: pmcd->piTypes[pmcd->iCurrentType] = iType;
300:
301: pmcd->iCurrentType++;
302: }
303:
304: //- else
305:
306: else
307: {
308: //- abort the traversal, fatal failure
309:
310: MathComponentDataStatusSet(pmcd, STATUS_OVERFLOW, ppist);
311: }
312: }
313: }
314:
315: //- else
316:
317: else
318: {
319: //- abort the traversal, fatal failure
320:
321: //t the current serial and type cursor give an indication
322: //t of what model component caused the failure
323:
324: MathComponentDataStatusSet(pmcd, STATUS_UNKNOWN_TYPE, ppist);
325: }
326:
327: return(1);
328: }
329:
330:
331: static
332: int
333: solver_channel_activation_processor(struct TreespaceTraversal *ptstr, void *pvUserdata)
334: {
335: //- set default result : ok
336:
337: int iResult = TSTR_PROCESSOR_SUCCESS;
338:
339: //- get actual symbol
340:
341: struct symtab_HSolveListElement *phsle = (struct symtab_HSolveListElement *)TstrGetActual(ptstr);
342:
343: //- get user data
344:
345: struct MathComponentData * pmcd = (struct MathComponentData *)pvUserdata;
346:
347: //- get current math component
348:
349: struct MathComponent * pmc = pmcd->pmc;
350:
351: struct ChannelAct * pca = (struct ChannelAct *)pmc;
352:
353: //- if conceptual gate
354:
355: if (instanceof_h_h_gate(phsle))
356: {
357: if (pmcd->iStatus == 1)
358: {
359: struct PoweredGateConcept * ppgc = &pca->pgc;
360:
361: //- get power
362:
363: double dPower = SymbolParameterResolveValue(phsle, ptstr->ppist, "POWER");
364:
365: int iPower = dPower;
366:
367: ppgc->iPower = iPower;
368:
369: //- get initial state
370:
371: double dInitActivation = SymbolParameterResolveValue(phsle, ptstr->ppist, "state_init");
372:
373: ppgc->gc.dInitActivation = dInitActivation;
374:
375: if (dPower == FLT_MAX
376: || dInitActivation == FLT_MAX)
377: {
378: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
379:
380: iResult = TSTR_PROCESSOR_ABORT;
381: }
382:
383: double dEntries = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_NUMBER_OF_TABLE_ENTRIES");
384:
385: if (dEntries != FLT_MAX)
386: {
387: ppgc->gc.htg.iEntries = dEntries;
388:
389: ppgc->gc.htg.hi.dStart = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_TABLE_START");
390: ppgc->gc.htg.hi.dEnd = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_TABLE_END");
391: ppgc->gc.htg.hi.dStep = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_TABLE_STEP");
392: }
393: else
394: {
395: ppgc->gc.htg.iEntries = INT_MAX;
396: }
397: }
398: else
399: {
400: MathComponentDataStatusSet(pmcd, STATUS_UNKNOWN_TYPE, ptstr->ppist);
401:
402: iResult = TSTR_PROCESSOR_ABORT;
403: }
404: }
405:
406: //- if gate kinetic
407:
408: else if (instanceof_gate_kinetic(phsle))
409: {
410: //! 2: forward, act
411: //! 3: backward, act
412:
413: if (pmcd->iStatus == 2
414: || pmcd->iStatus == 3)
415: {
416: struct PoweredGateConcept * ppgc = &pca->pgc;
417:
418: struct GateKinetic *pgk
419: = (pmcd->iStatus == 2
420: ? &ppgc->gc.parameters.gkA
421: : &ppgc->gc.parameters.gkB);
422:
423: //- initialize table index
424:
425: ppgc->gc.iTable = -1;
426:
427: //- if a hardcoded table is present
428:
429: double dHasTable = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_Has_Table");
430:
431: int iHasTable = 0;
432:
433: if (dHasTable != FLT_MAX)
434: {
435: iHasTable = dHasTable;
436: }
437:
438: if (iHasTable)
439: {
440: /* printf("warning: iHasTable has value %i\n", iHasTable); */
441:
442: }
443:
444: if (ppgc->gc.htg.iEntries != INT_MAX)
445: {
446: if (ppgc->gc.htg.hi.dStart != FLT_MAX
447: && ppgc->gc.htg.hi.dEnd != FLT_MAX
448: && ppgc->gc.htg.hi.dStep != FLT_MAX)
449: {
450: double *pdTable = calloc(ppgc->gc.htg.iEntries, sizeof(*pdTable));
451:
452: int i;
453:
454: for (i = 0 ; i < ppgc->gc.htg.iEntries ; i++)
455: {
456: char pcTable[50];
457:
458: sprintf(pcTable, "table[%i]", i);
459:
460: double d = SymbolParameterResolveValue(phsle, ptstr->ppist, pcTable);
461:
462: if (d != FLT_MAX)
463: {
464: pdTable[i] = d;
465: }
466: else
467: {
468: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
469:
470: iResult = TSTR_PROCESSOR_ABORT;
471:
472: break;
473: }
474: }
475:
476: //t would prefer to have all tests for pmcd->iStatus at the same place
477:
478: if (pmcd->iStatus == 2)
479: {
480: ppgc->gc.htg.pdA = pdTable;
481: }
482: else
483: {
484: ppgc->gc.htg.pdB = pdTable;
485: }
486: }
487: else
488: {
489: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
490:
491: iResult = TSTR_PROCESSOR_ABORT;
492: }
493: }
494:
495: //- else parameterized
496:
497: else
498: {
499: //- get HH_AB_Scale = 35.0e3
500:
501: double dHHScale = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_AB_Scale");
502:
503: pgk->dHHScale = dHHScale;
504:
505: //- get HH_AB_Mult = 0.0
506:
507: double dHHMult = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_AB_Mult");
508:
509: pgk->dHHMult = dHHMult;
510:
511: //- get HH_AB_Factor_Flag = -1.0
512:
513: double dHHFactorFlag = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_AB_Factor_Flag");
514:
515: int iHHFactorFlag = dHHFactorFlag;
516:
517: pgk->iHHFactorFlag = iHHFactorFlag;
518:
519: //- get HH_AB_Add = 0.0
520:
521: double dHHAdd = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_AB_Add");
522:
523: pgk->dHHAdd = dHHAdd;
524:
525: //- get HH_AB_Offset_E = 5.0e-3
526:
527: double dHHOffsetE = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_AB_Offset_E");
528:
529: pgk->dHHOffsetE = dHHOffsetE;
530:
531: //- get HH_AB_Tau = -10.0e-3
532:
533: double dHHTau = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_AB_Tau");
534:
535: pgk->dHHTau = dHHTau;
536:
537: if (dHHScale == FLT_MAX
538: || dHHMult == FLT_MAX
539: || dHHFactorFlag == FLT_MAX
540: || dHHAdd == FLT_MAX
541: || dHHOffsetE == FLT_MAX
542: || dHHTau == FLT_MAX)
543: {
544: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
545:
546: iResult = TSTR_PROCESSOR_ABORT;
547: }
548: }
549: }
550: else
551: {
552: MathComponentDataStatusSet(pmcd, STATUS_UNKNOWN_TYPE, ptstr->ppist);
553:
554: iResult = TSTR_PROCESSOR_ABORT;
555: }
556: }
557:
558: //- otherwise
559:
560: else
561: {
562: //- an error
563:
564: MathComponentDataStatusSet(pmcd, STATUS_UNKNOWN_TYPE, ptstr->ppist);
565:
566: iResult = TSTR_PROCESSOR_ABORT;
567: }
568:
569: //- if no error
570:
571: if (pmcd->iStatus > 0)
572: {
573: //- increment the status to indicate what component we have processed
574:
575: pmcd->iStatus++;
576:
577: if (pmcd->iStatus == 4)
578: {
579: pmcd->iStatus = 1;
580: }
581: }
582:
583: //- return result
584:
585: return(iResult);
586: }
587:
588:
589: static
590: double
591: TableAllocatorProcessor(struct TableAllocatorData *ptd, int iValue)
592: {
593: //- construct parameter name
594:
595: char pcValue[100];
596:
597: sprintf(pcValue, "value[%i]", iValue);
598:
599: //- resolve value
600:
601: double dResult = SymbolParameterResolveValue(ptd->phsle, ptd->ppist, pcValue);
602:
603: //- return result
604:
605: return(dResult);
606: }
607:
608:
609: static
610: int
611: solver_channel_activation_concentration_processor(struct TreespaceTraversal *ptstr, void *pvUserdata)
612: {
613: //- set default result : ok
614:
615: int iResult = TSTR_PROCESSOR_SUCCESS;
616:
617: //- get actual symbol
618:
619: struct symtab_HSolveListElement *phsle = (struct symtab_HSolveListElement *)TstrGetActual(ptstr);
620:
621: //- get user data
622:
623: struct MathComponentData * pmcd = (struct MathComponentData *)pvUserdata;
624:
625: //- get current math component
626:
627: struct MathComponent * pmc = pmcd->pmc;
628:
629: struct ChannelActConc * pcac = (struct ChannelActConc *)pmc;
630:
631: //- if conceptual gate
632:
633: if (instanceof_h_h_gate(phsle))
634: {
635: if (pmcd->iStatus == 1)
636: {
637: //- initial table index
638:
639: pcac->pgc.gc.iTable = -1;
640:
641: //- get power
642:
643: double dPower = SymbolParameterResolveValue(phsle, ptstr->ppist, "POWER");
644:
645: int iPower = dPower;
646:
647: pcac->pgc.iPower = iPower;
648:
649: //- get initial state
650:
651: double dInitActivation = SymbolParameterResolveValue(phsle, ptstr->ppist, "state_init");
652:
653: pcac->pgc.gc.dInitActivation = dInitActivation;
654:
655: if (dPower == FLT_MAX
656: || dInitActivation == FLT_MAX)
657: {
658: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
659:
660: iResult = TSTR_PROCESSOR_ABORT;
661: }
662:
663: double dEntries = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_NUMBER_OF_TABLE_ENTRIES");
664:
665: if (dEntries != FLT_MAX)
666: {
667: pcac->pgc.gc.htg.iEntries = dEntries;
668:
669: pcac->pgc.gc.htg.hi.dStart = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_TABLE_START");
670: pcac->pgc.gc.htg.hi.dEnd = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_TABLE_END");
671: pcac->pgc.gc.htg.hi.dStep = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_TABLE_STEP");
672: }
673: else
674: {
675: pcac->pgc.gc.htg.iEntries = INT_MAX;
676: }
677: }
678: else if (pmcd->iStatus == 4)
679: {
680: //- initial table index
681:
682: pcac->pac.ca.iTable = -1;
683:
684: //- get power
685:
686: double dPower = SymbolParameterResolveValue(phsle, ptstr->ppist, "POWER");
687:
688: int iPower = dPower;
689:
690: pcac->pac.iPower = iPower;
691:
692: //- get initial state
693:
694: double dInitActivation = SymbolParameterResolveValue(phsle, ptstr->ppist, "state_init");
695:
696: pcac->pac.ca.dInitActivation = dInitActivation;
697:
698: if (dPower == FLT_MAX
699: || dInitActivation == FLT_MAX)
700: {
701: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
702:
703: iResult = TSTR_PROCESSOR_ABORT;
704: }
705:
706: double dEntries = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_NUMBER_OF_TABLE_ENTRIES");
707:
708: if (dEntries != FLT_MAX)
709: {
710: pcac->pac.ca.htg.iEntries = dEntries;
711:
712: pcac->pac.ca.htg.hi.dStart = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_TABLE_START");
713: pcac->pac.ca.htg.hi.dEnd = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_TABLE_END");
714: pcac->pac.ca.htg.hi.dStep = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_TABLE_STEP");
715: }
716: else
717: {
718: pcac->pac.ca.htg.iEntries = INT_MAX;
719: }
720: }
721: else
722: {
723: MathComponentDataStatusSet(pmcd, STATUS_UNKNOWN_TYPE, ptstr->ppist);
724:
725: iResult = TSTR_PROCESSOR_ABORT;
726: }
727: }
728:
729: //- if gate kinetic
730:
731: else if (instanceof_gate_kinetic(phsle))
732: {
733: //! 2: forward, act
734: //! 3: backward, act
735: //! 5: forward, inact
736: //! 6: backward, inact
737:
738: if (pmcd->iStatus == 2
739: || pmcd->iStatus == 3)
740: {
741: struct PoweredGateConcept * ppgc = &pcac->pgc;
742:
743: struct GateKinetic *pgk
744: = (pmcd->iStatus == 2
745: ? &ppgc->gc.parameters.gkA
746: : &ppgc->gc.parameters.gkB);
747:
748: //- initialize table index
749:
750: ppgc->gc.iTable = -1;
751:
752: double dHasTable = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_Has_Table");
753:
754: int iHasTable = 0;
755:
756: if (dHasTable != FLT_MAX)
757: {
758: iHasTable = dHasTable;
759: }
760:
761: if (iHasTable)
762: {
763: /* printf("warning: iHasTable has value %i\n", iHasTable); */
764:
765: }
766:
767: if (ppgc->gc.htg.iEntries != INT_MAX)
768: {
769: if (ppgc->gc.htg.hi.dStart != FLT_MAX
770: && ppgc->gc.htg.hi.dEnd != FLT_MAX
771: && ppgc->gc.htg.hi.dStep != FLT_MAX)
772: {
773: double *pdTable = calloc(ppgc->gc.htg.iEntries, sizeof(*pdTable));
774:
775: int i;
776:
777: for (i = 0 ; i < ppgc->gc.htg.iEntries ; i++)
778: {
779: char pcTable[50];
780:
781: sprintf(pcTable, "table[%i]", i);
782:
783: double d = SymbolParameterResolveValue(phsle, ptstr->ppist, pcTable);
784:
785: if (d != FLT_MAX)
786: {
787: pdTable[i] = d;
788: }
789: else
790: {
791: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
792:
793: iResult = TSTR_PROCESSOR_ABORT;
794:
795: break;
796: }
797: }
798:
799: //t would prefer to have all tests for pmcd->iStatus at the same place
800:
801: if (pmcd->iStatus == 2)
802: {
803: ppgc->gc.htg.pdA = pdTable;
804: }
805: else
806: {
807: ppgc->gc.htg.pdB = pdTable;
808: }
809: }
810: else
811: {
812: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
813:
814: iResult = TSTR_PROCESSOR_ABORT;
815: }
816: }
817:
818: //- else parameterized
819:
820: else
821: {
822: //- get HH_AB_Scale = 35.0e3
823:
824: double dHHScale = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_AB_Scale");
825:
826: pgk->dHHScale = dHHScale;
827:
828: //- get HH_AB_Mult = 0.0
829:
830: double dHHMult = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_AB_Mult");
831:
832: pgk->dHHMult = dHHMult;
833:
834: //- get HH_AB_Factor_Flag = -1.0
835:
836: double dHHFactorFlag = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_AB_Factor_Flag");
837:
838: int iHHFactorFlag = dHHFactorFlag;
839:
840: pgk->iHHFactorFlag = iHHFactorFlag;
841:
842: //- get HH_AB_Add = 0.0
843:
844: double dHHAdd = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_AB_Add");
845:
846: pgk->dHHAdd = dHHAdd;
847:
848: //- get HH_AB_Offset_E = 5.0e-3
849:
850: double dHHOffsetE = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_AB_Offset_E");
851:
852: pgk->dHHOffsetE = dHHOffsetE;
853:
854: //- get HH_AB_Tau = -10.0e-3
855:
856: double dHHTau = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_AB_Tau");
857:
858: pgk->dHHTau = dHHTau;
859:
860: if (dHHScale == FLT_MAX
861: || dHHMult == FLT_MAX
862: || dHHFactorFlag == FLT_MAX
863: || dHHAdd == FLT_MAX
864: || dHHOffsetE == FLT_MAX
865: || dHHTau == FLT_MAX)
866: {
867: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
868:
869: iResult = TSTR_PROCESSOR_ABORT;
870: }
871: }
872: }
873: else
874: {
875: MathComponentDataStatusSet(pmcd, STATUS_UNKNOWN_TYPE, ptstr->ppist);
876:
877: iResult = TSTR_PROCESSOR_ABORT;
878: }
879: }
880:
881: //- if activator
882:
883: else if (instanceof_concentration_gate_kinetic(phsle))
884: {
885: //- if forward
886:
887: if (pmcd->iStatus == 5)
888: {
889: //- initialize table index
890:
891: pcac->pac.ca.iTable = -1;
892:
893: double dHasTable = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_Has_Table");
894:
895: int iHasTable = 0;
896:
897: if (dHasTable != FLT_MAX)
898: {
899: iHasTable = dHasTable;
900: }
901:
902: if (iHasTable)
903: {
904: /* printf("warning: iHasTable has value %i\n", iHasTable); */
905:
906: }
907:
908: if (pcac->pac.ca.htg.iEntries != INT_MAX)
909: {
910: if (pcac->pac.ca.htg.hi.dStart != FLT_MAX
911: && pcac->pac.ca.htg.hi.dEnd != FLT_MAX
912: && pcac->pac.ca.htg.hi.dStep != FLT_MAX)
913: {
914: double *pdTable = calloc(pcac->pac.ca.htg.iEntries, sizeof(*pdTable));
915:
916: int i;
917:
918: for (i = 0 ; i < pcac->pac.ca.htg.iEntries ; i++)
919: {
920: char pcTable[50];
921:
922: sprintf(pcTable, "table[%i]", i);
923:
924: double d = SymbolParameterResolveValue(phsle, ptstr->ppist, pcTable);
925:
926: if (d != FLT_MAX)
927: {
928: pdTable[i] = d;
929: }
930: else
931: {
932: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
933:
934: iResult = TSTR_PROCESSOR_ABORT;
935:
936: break;
937: }
938: }
939: }
940: else
941: {
942: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
943:
944: iResult = TSTR_PROCESSOR_ABORT;
945: }
946: }
947:
948: //- else parameterized
949:
950: else
951: {
952: //- basal level, A in EDS1994
953:
954: double dBasalLevel = SymbolParameterResolveValue(phsle, ptstr->ppist, "Base");
955:
956: pcac->pac.ca.parameters.dBasalLevel = dBasalLevel;
957:
958: //- time constant, B in EDS1994
959:
960: double dTau = SymbolParameterResolveValue(phsle, ptstr->ppist, "Tau");
961:
962: pcac->pac.ca.parameters.dTau = dTau;
963:
964: if (dBasalLevel == FLT_MAX
965: || dTau == FLT_MAX)
966: {
967: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
968:
969: iResult = TSTR_PROCESSOR_ABORT;
970: }
971: }
972: }
973: else
974: {
975: MathComponentDataStatusSet(pmcd, STATUS_UNKNOWN_TYPE, ptstr->ppist);
976:
977: iResult = TSTR_PROCESSOR_ABORT;
978: }
979: }
980:
981: //- otherwise
982:
983: else
984: {
985: //- an error
986:
987: MathComponentDataStatusSet(pmcd, STATUS_UNKNOWN_TYPE, ptstr->ppist);
988: }
989:
990: //- if no error
991:
992: if (pmcd->iStatus > 0)
993: {
994: //- increment the status to indicate what component we have processed
995:
996: pmcd->iStatus++;
997:
998: if (pmcd->iStatus == 6)
999: {
1000: pmcd->iStatus = 1;
1001: }
1002: }
1003:
1004: //- return result
1005:
1006: return(iResult);
1007: }
1008:
1009:
1010: static
1011: int
1012: solver_channel_activation_inactivation_processor(struct TreespaceTraversal *ptstr, void *pvUserdata)
1013: {
1014: //- set default result : ok
1015:
1016: int iResult = TSTR_PROCESSOR_SUCCESS;
1017:
1018: //- get actual symbol
1019:
1020: struct symtab_HSolveListElement *phsle = (struct symtab_HSolveListElement *)TstrGetActual(ptstr);
1021:
1022: //- get user data
1023:
1024: struct MathComponentData * pmcd = (struct MathComponentData *)pvUserdata;
1025:
1026: //- get current math component
1027:
1028: struct MathComponent * pmc = pmcd->pmc;
1029:
1030: struct ChannelActInact * pcai = (struct ChannelActInact *)pmc;
1031:
1032: //- if conceptual gate
1033:
1034: if (instanceof_h_h_gate(phsle))
1035: {
1036: if (pmcd->iStatus == 1
1037: || pmcd->iStatus == 4)
1038: {
1039: struct PoweredGateConcept * ppgc
1040: = pmcd->iStatus == 1
1041: ? &pcai->pgcActivation
1042: : &pcai->pgcInactivation;
1043:
1044: //- get power
1045:
1046: double dPower = SymbolParameterResolveValue(phsle, ptstr->ppist, "POWER");
1047:
1048: int iPower = dPower;
1049:
1050: ppgc->iPower = iPower;
1051:
1052: //- get initial state
1053:
1054: double dInitActivation = SymbolParameterResolveValue(phsle, ptstr->ppist, "state_init");
1055:
1056: ppgc->gc.dInitActivation = dInitActivation;
1057:
1058: if (dPower == FLT_MAX
1059: || dInitActivation == FLT_MAX)
1060: {
1061: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
1062:
1063: iResult = TSTR_PROCESSOR_ABORT;
1064: }
1065:
1066: double dEntries = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_NUMBER_OF_TABLE_ENTRIES");
1067:
1068: if (dEntries != FLT_MAX)
1069: {
1070: ppgc->gc.htg.iEntries = dEntries;
1071:
1072: ppgc->gc.htg.hi.dStart = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_TABLE_START");
1073: ppgc->gc.htg.hi.dEnd = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_TABLE_END");
1074: ppgc->gc.htg.hi.dStep = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_TABLE_STEP");
1075: }
1076: else
1077: {
1078: ppgc->gc.htg.iEntries = INT_MAX;
1079: }
1080: }
1081: else
1082: {
1083: MathComponentDataStatusSet(pmcd, STATUS_UNKNOWN_TYPE, ptstr->ppist);
1084:
1085: iResult = TSTR_PROCESSOR_ABORT;
1086: }
1087: }
1088:
1089: //- if gate kinetic
1090:
1091: else if (instanceof_gate_kinetic(phsle))
1092: {
1093: //! 2: forward, act
1094: //! 3: backward, act
1095: //! 5: forward, inact
1096: //! 6: backward, inact
1097:
1098: if (pmcd->iStatus == 2
1099: || pmcd->iStatus == 3
1100: || pmcd->iStatus == 5
1101: || pmcd->iStatus == 6)
1102: {
1103: struct PoweredGateConcept * ppgc
1104: = (pmcd->iStatus == 2
1105: || pmcd->iStatus == 3
1106: ? &pcai->pgcActivation
1107: : &pcai->pgcInactivation);
1108:
1109: struct GateKinetic *pgk
1110: = (pmcd->iStatus == 2
1111: || pmcd->iStatus == 5
1112: ? &ppgc->gc.parameters.gkA
1113: : &ppgc->gc.parameters.gkB);
1114:
1115: //- initialize table index
1116:
1117: ppgc->gc.iTable = -1;
1118:
1119: double dHasTable = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_Has_Table");
1120:
1121: int iHasTable = 0;
1122:
1123: if (dHasTable != FLT_MAX)
1124: {
1125: iHasTable = dHasTable;
1126: }
1127:
1128: if (iHasTable)
1129: {
1130: /* printf("warning: iHasTable has value %i\n", iHasTable); */
1131:
1132: }
1133:
1134: if (ppgc->gc.htg.iEntries != INT_MAX)
1135: {
1136: if (ppgc->gc.htg.hi.dStart != FLT_MAX
1137: && ppgc->gc.htg.hi.dEnd != FLT_MAX
1138: && ppgc->gc.htg.hi.dStep != FLT_MAX)
1139: {
1140: double *pdTable = calloc(ppgc->gc.htg.iEntries, sizeof(*pdTable));
1141:
1142: int i;
1143:
1144: for (i = 0 ; i < ppgc->gc.htg.iEntries ; i++)
1145: {
1146: char pcTable[50];
1147:
1148: sprintf(pcTable, "table[%i]", i);
1149:
1150: double d = SymbolParameterResolveValue(phsle, ptstr->ppist, pcTable);
1151:
1152: if (d != FLT_MAX)
1153: {
1154: pdTable[i] = d;
1155: }
1156: else
1157: {
1158: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
1159:
1160: iResult = TSTR_PROCESSOR_ABORT;
1161:
1162: break;
1163: }
1164: }
1165:
1166: //t would prefer to have all tests for pmcd->iStatus at the same place
1167:
1168: if (pmcd->iStatus == 2
1169: || pmcd->iStatus == 5)
1170: { //t store number of entries in the table
1171: ppgc->gc.htg.pdA = pdTable;
1172: }
1173: else
1174: { //t compare number of entries with stored number
1175: ppgc->gc.htg.pdB = pdTable;
1176: }
1177: }
1178: else
1179: {
1180: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
1181:
1182: iResult = TSTR_PROCESSOR_ABORT;
1183: }
1184: }
1185:
1186: //- else parameterized
1187:
1188: else
1189: {
1190: //- get HH_AB_Scale = 35.0e3
1191:
1192: double dHHScale = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_AB_Scale");
1193:
1194: pgk->dHHScale = dHHScale;
1195:
1196: //- get HH_AB_Mult = 0.0
1197:
1198: double dHHMult = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_AB_Mult");
1199:
1200: pgk->dHHMult = dHHMult;
1201:
1202: //- get HH_AB_FactorFlag = -1.0
1203:
1204: double dHHFactorFlag = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_AB_Factor_Flag");
1205:
1206: int iHHFactorFlag = dHHFactorFlag;
1207:
1208: pgk->iHHFactorFlag = iHHFactorFlag;
1209:
1210: //- get HH_AB_Add = 0.0
1211:
1212: double dHHAdd = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_AB_Add");
1213:
1214: pgk->dHHAdd = dHHAdd;
1215:
1216: //- get HH_AB_Offset_E = 5.0e-3
1217:
1218: double dHHOffsetE = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_AB_Offset_E");
1219:
1220: pgk->dHHOffsetE = dHHOffsetE;
1221:
1222: //- get HH_AB_Tau = -10.0e-3
1223:
1224: double dHHTau = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_AB_Tau");
1225:
1226: pgk->dHHTau = dHHTau;
1227:
1228: if (dHHScale == FLT_MAX
1229: || dHHMult == FLT_MAX
1230: || dHHFactorFlag == FLT_MAX
1231: || dHHAdd == FLT_MAX
1232: || dHHOffsetE == FLT_MAX
1233: || dHHTau == FLT_MAX)
1234: {
1235: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
1236:
1237: iResult = TSTR_PROCESSOR_ABORT;
1238: }
1239: }
1240: }
1241: else
1242: {
1243: MathComponentDataStatusSet(pmcd, STATUS_UNKNOWN_TYPE, ptstr->ppist);
1244:
1245: iResult = TSTR_PROCESSOR_ABORT;
1246: }
1247: }
1248:
1249: //- otherwise
1250:
1251: else
1252: {
1253: //- an error
1254:
1255: MathComponentDataStatusSet(pmcd, STATUS_UNKNOWN_TYPE, ptstr->ppist);
1256:
1257: iResult = TSTR_PROCESSOR_ABORT;
1258: }
1259:
1260: //- if no error
1261:
1262: if (pmcd->iStatus > 0)
1263: {
1264: //- increment the status to indicate what component we have processed
1265:
1266: pmcd->iStatus++;
1267:
1268: if (pmcd->iStatus == 7)
1269: {
1270: pmcd->iStatus = 1;
1271: }
1272: }
1273:
1274: //- return result
1275:
1276: return(iResult);
1277: }
1278:
1279:
1280: static
1281: int
1282: solver_channel_persistent_steadystate_dualtau_processor(struct TreespaceTraversal *ptstr, void *pvUserdata)
1283: {
1284: //- set default result : ok
1285:
1286: int iResult = TSTR_PROCESSOR_SUCCESS;
1287:
1288: //- get actual symbol
1289:
1290: struct symtab_HSolveListElement *phsle = (struct symtab_HSolveListElement *)TstrGetActual(ptstr);
1291:
1292: //- get user data
1293:
1294: struct MathComponentData * pmcd = (struct MathComponentData *)pvUserdata;
1295:
1296: //- get current math component
1297:
1298: struct MathComponent * pmc = pmcd->pmc;
1299:
1300: struct ChannelPersistentSteadyStateDualTau * pcpsdt
1301: = (struct ChannelPersistentSteadyStateDualTau *)pmc;
1302:
1303: //- if conceptual gate
1304:
1305: if (instanceof_h_h_gate(phsle))
1306: {
1307: if (pmcd->iStatus == 1)
1308: {
1309: //- initialize table pointers
1310:
1311: pcpsdt->iFirstTable = -1;
1312: pcpsdt->iSecondTable = -1;
1313:
1314: //- get powers
1315:
1316: double dFirstPower = SymbolParameterResolveValue(phsle, ptstr->ppist, "iFirstPower");
1317: int iFirstPower = dFirstPower;
1318: pcpsdt->iFirstPower = iFirstPower;
1319:
1320: double dSecondPower = SymbolParameterResolveValue(phsle, ptstr->ppist, "iSecondPower");
1321: int iSecondPower = dSecondPower;
1322: pcpsdt->iSecondPower = iSecondPower;
1323:
1324: //- get initial states
1325:
1326: double dFirstInitActivation = SymbolParameterResolveValue(phsle, ptstr->ppist, "dFirstInitActivation");
1327: pcpsdt->dFirstInitActivation = dFirstInitActivation;
1328:
1329: double dSecondInitActivation = SymbolParameterResolveValue(phsle, ptstr->ppist, "dSecondInitActivation");
1330: pcpsdt->dSecondInitActivation = dSecondInitActivation;
1331:
1332: //- get steady states
1333:
1334: double dFirstSteadyState = SymbolParameterResolveValue(phsle, ptstr->ppist, "dFirstSteadyState");
1335: pcpsdt->parameters1.dSteadyState = dFirstSteadyState;
1336:
1337: double dSecondSteadyState = SymbolParameterResolveValue(phsle, ptstr->ppist, "dSecondSteadyState");
1338: pcpsdt->parameters2.dSteadyState = dSecondSteadyState;
1339:
1340: if (dFirstPower == FLT_MAX
1341: || dFirstInitActivation == FLT_MAX
1342: || dFirstSteadyState == FLT_MAX
1343: || dSecondPower == FLT_MAX
1344: || dSecondInitActivation == FLT_MAX
1345: || dSecondSteadyState == FLT_MAX)
1346: {
1347: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
1348:
1349: iResult = TSTR_PROCESSOR_ABORT;
1350: }
1351: }
1352: else
1353: {
1354: MathComponentDataStatusSet(pmcd, STATUS_UNKNOWN_TYPE, ptstr->ppist);
1355:
1356: iResult = TSTR_PROCESSOR_ABORT;
1357: }
1358: }
1359:
1360: //- if gate kinetic
1361:
1362: else if (instanceof_gate_kinetic(phsle))
1363: {
1364: //! 2: tau 1
1365: //! 3: tau 2
1366:
1367: if (pmcd->iStatus == 2
1368: || pmcd->iStatus == 3)
1369: {
1370: struct dualtaucomponent * pdtc
1371: = (pmcd->iStatus == 2
1372: ? &pcpsdt->parameters1.tau
1373: : &pcpsdt->parameters2.tau);
1374:
1375: double dHasTable = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_Has_Table");
1376:
1377: int iHasTable = 0;
1378:
1379: if (dHasTable != FLT_MAX)
1380: {
1381: iHasTable = dHasTable;
1382: }
1383:
1384: if (iHasTable)
1385: {
1386: printf("warning: iHasTable has value %i\n", iHasTable);
1387:
1388: }
1389: else
1390: {
1391: //- get Multiplier = 35.0e3
1392:
1393: double dMultiplier = SymbolParameterResolveValue(phsle, ptstr->ppist, "dMultiplier");
1394:
1395: pdtc->dMultiplier = dMultiplier;
1396:
1397: //- get DeNominatorOffset = 0.0
1398:
1399: double dDeNominatorOffset = SymbolParameterResolveValue(phsle, ptstr->ppist, "dDeNominatorOffset");
1400:
1401: pdtc->dDeNominatorOffset = dDeNominatorOffset;
1402:
1403: //- get MembraneOffset = 5.0e-3
1404:
1405: double dMembraneOffset = SymbolParameterResolveValue(phsle, ptstr->ppist, "dMembraneOffset");
1406:
1407: pdtc->dMembraneOffset = dMembraneOffset;
1408:
1409: //- get TauDenormalizer = -10.0e-3
1410:
1411: double dTauDenormalizer = SymbolParameterResolveValue(phsle, ptstr->ppist, "dTauDenormalizer");
1412:
1413: pdtc->dTauDenormalizer = dTauDenormalizer;
1414:
1415: if (dMultiplier == FLT_MAX
1416: || dDeNominatorOffset == FLT_MAX
1417: || dMembraneOffset == FLT_MAX
1418: || dTauDenormalizer == FLT_MAX)
1419: {
1420: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
1421:
1422: iResult = TSTR_PROCESSOR_ABORT;
1423: }
1424: }
1425: }
1426: else
1427: {
1428: MathComponentDataStatusSet(pmcd, STATUS_UNKNOWN_TYPE, ptstr->ppist);
1429:
1430: iResult = TSTR_PROCESSOR_ABORT;
1431: }
1432: }
1433:
1434: //- otherwise
1435:
1436: else
1437: {
1438: //- an error
1439:
1440: MathComponentDataStatusSet(pmcd, STATUS_UNKNOWN_TYPE, ptstr->ppist);
1441:
1442: iResult = TSTR_PROCESSOR_ABORT;
1443: }
1444:
1445: //- if no error
1446:
1447: if (pmcd->iStatus > 0)
1448: {
1449: //- increment the status to indicate what component we have processed
1450:
1451: pmcd->iStatus++;
1452:
1453: if (pmcd->iStatus == 4)
1454: {
1455: pmcd->iStatus = 1;
1456: }
1457: }
1458:
1459: //- return result
1460:
1461: return(iResult);
1462: }
1463:
1464:
1465: static
1466: int
1467: solver_channel_persistent_steadystate_tau_processor(struct TreespaceTraversal *ptstr, void *pvUserdata)
1468: {
1469: //- set default result : ok
1470:
1471: int iResult = TSTR_PROCESSOR_SUCCESS;
1472:
1473: //- get actual symbol
1474:
1475: struct symtab_HSolveListElement *phsle = (struct symtab_HSolveListElement *)TstrGetActual(ptstr);
1476:
1477: //- get user data
1478:
1479: struct MathComponentData * pmcd = (struct MathComponentData *)pvUserdata;
1480:
1481: //- get current math component
1482:
1483: struct MathComponent * pmc = pmcd->pmc;
1484:
1485: struct ChannelPersistentSteadyStateTau * pcpst
1486: = (struct ChannelPersistentSteadyStateTau *)pmc;
1487:
1488: //- if conceptual gate
1489:
1490: if (instanceof_h_h_gate(phsle))
1491: {
1492: if (pmcd->iStatus == 1)
1493: {
1494: //- initialize table pointer
1495:
1496: pcpst->iTable = -1;
1497:
1498: //- get power
1499:
1500: double dPower = SymbolParameterResolveValue(phsle, ptstr->ppist, "POWER");
1501: int iPower = dPower;
1502: pcpst->iPower = iPower;
1503:
1504: //- get initial states
1505:
1506: double dInitActivation = SymbolParameterResolveValue(phsle, ptstr->ppist, "state_init");
1507: pcpst->dInitActivation = dInitActivation;
1508:
1509: if (dPower == FLT_MAX
1510: || dInitActivation == FLT_MAX)
1511: {
1512: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
1513:
1514: iResult = TSTR_PROCESSOR_ABORT;
1515: }
1516: }
1517: else
1518: {
1519: MathComponentDataStatusSet(pmcd, STATUS_UNKNOWN_TYPE, ptstr->ppist);
1520:
1521: iResult = TSTR_PROCESSOR_ABORT;
1522: }
1523: }
1524:
1525: //- if gate kinetic
1526:
1527: else if (instanceof_gate_kinetic(phsle))
1528: {
1529: if (pmcd->iStatus == 2)
1530: {
1531: struct single_steady_state * pss = &pcpst->parameters.ss;
1532:
1533: double dHasTable = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_Has_Table");
1534:
1535: int iHasTable = 0;
1536:
1537: if (dHasTable != FLT_MAX)
1538: {
1539: iHasTable = dHasTable;
1540: }
1541:
1542: if (iHasTable)
1543: {
1544: printf("warning: iHasTable has value %i\n", iHasTable);
1545:
1546: }
1547: else
1548: {
1549: //- get Nominator
1550:
1551: double dNominator = SymbolParameterResolveValue(phsle, ptstr->ppist, "dNominator");
1552:
1553: pss->dNominator = dNominator;
1554:
1555: //- get Multiplier1
1556:
1557: double dMultiplier1 = SymbolParameterResolveValue(phsle, ptstr->ppist, "dMultiplier1");
1558:
1559: pss->dMultiplier1 = dMultiplier1;
1560:
1561: //- get MembraneOffset1
1562:
1563: double dMembraneOffset1 = SymbolParameterResolveValue(phsle, ptstr->ppist, "dMembraneOffset1");
1564:
1565: pss->dMembraneOffset1 = dMembraneOffset1;
1566:
1567: //- get TauDenormalizer1
1568:
1569: double dTauDenormalizer1 = SymbolParameterResolveValue(phsle, ptstr->ppist, "dTauDenormalizer1");
1570:
1571: pss->dTauDenormalizer1 = dTauDenormalizer1;
1572:
1573: //- get Multiplier2
1574:
1575: double dMultiplier2 = SymbolParameterResolveValue(phsle, ptstr->ppist, "dMultiplier2");
1576:
1577: pss->dMultiplier2 = dMultiplier2;
1578:
1579: //- get MembraneOffset2
1580:
1581: double dMembraneOffset2 = SymbolParameterResolveValue(phsle, ptstr->ppist, "dMembraneOffset2");
1582:
1583: pss->dMembraneOffset2 = dMembraneOffset2;
1584:
1585: //- get TauDenormalizer2
1586:
1587: double dTauDenormalizer2 = SymbolParameterResolveValue(phsle, ptstr->ppist, "dTauDenormalizer2");
1588:
1589: pss->dTauDenormalizer2 = dTauDenormalizer2;
1590:
1591: if (dNominator == FLT_MAX
1592: || dMultiplier1 == FLT_MAX
1593: || dMembraneOffset1 == FLT_MAX
1594: || dTauDenormalizer1 == FLT_MAX
1595: || dMultiplier2 == FLT_MAX
1596: || dMembraneOffset2 == FLT_MAX
1597: || dTauDenormalizer2 == FLT_MAX)
1598: {
1599: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
1600:
1601: iResult = TSTR_PROCESSOR_ABORT;
1602: }
1603: }
1604: }
1605: else if (pmcd->iStatus == 3)
1606: {
1607: struct single_time_constant * ptc = &pcpst->parameters.tc;
1608:
1609: double dHasTable = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_Has_Table");
1610:
1611: int iHasTable = 0;
1612:
1613: if (dHasTable != FLT_MAX)
1614: {
1615: iHasTable = dHasTable;
1616: }
1617:
1618: if (iHasTable)
1619: {
1620: printf("warning: iHasTable has value %i\n", iHasTable);
1621:
1622: }
1623: else
1624: {
1625: //- get Nominator
1626:
1627: double dNominator = SymbolParameterResolveValue(phsle, ptstr->ppist, "dNominator");
1628:
1629: ptc->dNominator = dNominator;
1630:
1631: //- get DeNominatorOffset
1632:
1633: double dDeNominatorOffset = SymbolParameterResolveValue(phsle, ptstr->ppist, "dDeNominatorOffset");
1634:
1635: ptc->dDeNominatorOffset = dDeNominatorOffset;
1636:
1637: //- get MembraneOffset
1638:
1639: double dMembraneOffset = SymbolParameterResolveValue(phsle, ptstr->ppist, "dMembraneOffset");
1640:
1641: ptc->dMembraneOffset = dMembraneOffset;
1642:
1643: //- get TauDenormalizer
1644:
1645: double dTauDenormalizer = SymbolParameterResolveValue(phsle, ptstr->ppist, "dTauDenormalizer");
1646:
1647: ptc->dTauDenormalizer = dTauDenormalizer;
1648:
1649: if (dNominator == FLT_MAX
1650: || dDeNominatorOffset == FLT_MAX
1651: || dMembraneOffset == FLT_MAX
1652: || dTauDenormalizer == FLT_MAX)
1653: {
1654: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
1655:
1656: iResult = TSTR_PROCESSOR_ABORT;
1657: }
1658: }
1659: }
1660: else
1661: {
1662: MathComponentDataStatusSet(pmcd, STATUS_UNKNOWN_TYPE, ptstr->ppist);
1663:
1664: iResult = TSTR_PROCESSOR_ABORT;
1665: }
1666: }
1667:
1668: //- otherwise
1669:
1670: else
1671: {
1672: //- an error
1673:
1674: MathComponentDataStatusSet(pmcd, STATUS_UNKNOWN_TYPE, ptstr->ppist);
1675:
1676: iResult = TSTR_PROCESSOR_ABORT;
1677: }
1678:
1679: //- if no error
1680:
1681: if (pmcd->iStatus > 0)
1682: {
1683: //- increment the status to indicate what component we have processed
1684:
1685: pmcd->iStatus++;
1686:
1687: if (pmcd->iStatus == 4)
1688: {
1689: pmcd->iStatus = 1;
1690: }
1691: }
1692:
1693: //- return result
1694:
1695: return(iResult);
1696: }
1697:
1698:
1699: static
1700: int
1701: solver_channel_springmass_processor(struct TreespaceTraversal *ptstr, void *pvUserdata)
1702: {
1703: //- set default result : ok
1704:
1705: int iResult = TSTR_PROCESSOR_SUCCESS;
1706:
1707: //- get actual symbol
1708:
1709: struct symtab_HSolveListElement *phsle = (struct symtab_HSolveListElement *)TstrGetActual(ptstr);
1710:
1711: //- get user data
1712:
1713: struct MathComponentData * pmcd = (struct MathComponentData *)pvUserdata;
1714:
1715: //- get current math component
1716:
1717: struct MathComponent * pmc = pmcd->pmc;
1718:
1719: struct ChannelSpringMass * pcsm
1720: = (struct ChannelSpringMass *)pmc;
1721:
1722: //- if domain mapper
1723:
1724: if (instanceof_attachment(phsle))
1725: {
1726: if (pmcd->iStatus == 1
1727: || pmcd->iStatus == 2)
1728: {
1729: //- get filename of event list
1730:
1731: //t should use ParameterResolveSymbol()
1732:
1733: struct symtab_Parameters *pparEvents
1734: = SymbolFindParameter(phsle, ptstr->ppist, "EVENT_FILENAME");
1735:
1736: if (pparEvents)
1737: {
1738: char *pcEvents = ParameterGetString(pparEvents);
1739:
1740: //t hardcoded connection with the neurospaces model container.
1741: //t filename qualification must come in a separate software component.
1742:
1743: char *pcEventsQualified
1744: = NeurospacesQualifyFilename(pmcd->pheccer->pts->ptsd->pneuro, pcEvents);
1745:
1746: if (pcEvents && !pcEventsQualified)
1747: {
1748: MathComponentDataStatusSet(pmcd, STATUS_UNQUALIFIABLE_FILENAME, ptstr->ppist);
1749:
1750: iResult = TSTR_PROCESSOR_ABORT;
1751: }
1752:
1753: pcsm->pcEventTimes = pcEventsQualified;
1754: }
1755:
1756: //t not sure yet about connectivity, needs a separate pass
1757: //t as in the genesis/hsolve/neurospaces implementation.
1758:
1759: }
1760: else
1761: {
1762: MathComponentDataStatusSet(pmcd, STATUS_UNKNOWN_TYPE, ptstr->ppist);
1763:
1764: iResult = TSTR_PROCESSOR_ABORT;
1765: }
1766: }
1767:
1768: //- if equation
1769:
1770: else if (instanceof_equation(phsle))
1771: {
1772: if (pmcd->iStatus == 1
1773: || pmcd->iStatus == 2)
1774: {
1775: //- initialize table pointer
1776:
1777: pcsm->iTable = -1;
1778:
1779: //- get first time constants
1780:
1781: double dTau1 = SymbolParameterResolveValue(phsle, ptstr->ppist, "TAU1");
1782: pcsm->parameters.dTau1 = dTau1;
1783:
1784: double dTau2 = SymbolParameterResolveValue(phsle, ptstr->ppist, "TAU2");
1785: pcsm->parameters.dTau2 = dTau2;
1786:
1787: //t perhaps if only tau1 is defined, I should make tau2
1788: //t equal to tau1 and treat it as a single exponential
1789:
1790: if (dTau1 == FLT_MAX
1791: || dTau2 == FLT_MAX)
1792: {
1793: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
1794:
1795: iResult = TSTR_PROCESSOR_ABORT;
1796: }
1797:
1798: //- get initial states
1799:
1800: double dInitX = SymbolParameterResolveValue(phsle, ptstr->ppist, "state_init_x");
1801:
1802: if (dInitX == FLT_MAX)
1803: {
1804: pcsm->dInitX = 0;
1805: }
1806: else
1807: {
1808: pcsm->dInitX = dInitX;
1809: }
1810:
1811: double dInitY = SymbolParameterResolveValue(phsle, ptstr->ppist, "state_init_y");
1812:
1813: if (dInitY == FLT_MAX)
1814: {
1815: pcsm->dInitY = 0;
1816: }
1817: else
1818: {
1819: pcsm->dInitY = dInitY;
1820: }
1821:
1822: }
1823: else
1824: {
1825: MathComponentDataStatusSet(pmcd, STATUS_UNKNOWN_TYPE, ptstr->ppist);
1826:
1827: iResult = TSTR_PROCESSOR_ABORT;
1828: }
1829: }
1830:
1831: //t have to do attachment points
1832:
1833: //- otherwise
1834:
1835: else
1836: {
1837: //- an error
1838:
1839: MathComponentDataStatusSet(pmcd, STATUS_UNKNOWN_TYPE, ptstr->ppist);
1840:
1841: iResult = TSTR_PROCESSOR_ABORT;
1842: }
1843:
1844: //- if no error
1845:
1846: if (pmcd->iStatus > 0)
1847: {
1848: //- increment the status to indicate what component we have processed
1849:
1850: pmcd->iStatus++;
1851:
1852: if (pmcd->iStatus == 2)
1853: {
1854: pmcd->iStatus = 1;
1855: }
1856: }
1857:
1858: //- return result
1859:
1860: return(iResult);
1861: }
1862:
1863:
1864: static
1865: int
1866: solver_channel_steadystate_steppedtau_processor(struct TreespaceTraversal *ptstr, void *pvUserdata)
1867: {
1868: //- set default result : ok
1869:
1870: int iResult = TSTR_PROCESSOR_SUCCESS;
1871:
1872: //- get actual symbol
1873:
1874: struct symtab_HSolveListElement *phsle = (struct symtab_HSolveListElement *)TstrGetActual(ptstr);
1875:
1876: //- get user data
1877:
1878: struct MathComponentData * pmcd = (struct MathComponentData *)pvUserdata;
1879:
1880: //- get current math component
1881:
1882: struct MathComponent * pmc = pmcd->pmc;
1883:
1884: struct ChannelSteadyStateSteppedTau * pcpsdt
1885: = (struct ChannelSteadyStateSteppedTau *)pmc;
1886:
1887: //- if conceptual gate
1888:
1889: if (instanceof_h_h_gate(phsle))
1890: {
1891: if (pmcd->iStatus == 1)
1892: {
1893: //- initialize table pointer
1894:
1895: pcpsdt->iFirstTable = -1;
1896:
1897: //- get power
1898:
1899: double dFirstPower = SymbolParameterResolveValue(phsle, ptstr->ppist, "POWER");
1900: int iFirstPower = dFirstPower;
1901: pcpsdt->iFirstPower = iFirstPower;
1902:
1903: //- get initial state
1904:
1905: double dFirstInitActivation = SymbolParameterResolveValue(phsle, ptstr->ppist, "state_init");
1906: pcpsdt->dFirstInitActivation = dFirstInitActivation;
1907:
1908: if (dFirstPower == FLT_MAX
1909: || dFirstInitActivation == FLT_MAX)
1910: {
1911: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
1912:
1913: iResult = TSTR_PROCESSOR_ABORT;
1914: }
1915: }
1916: else if (pmcd->iStatus == 8)
1917: {
1918: //- initialize table pointer
1919:
1920: pcpsdt->iSecondTable = -1;
1921:
1922: //- get power
1923:
1924: double dSecondPower = SymbolParameterResolveValue(phsle, ptstr->ppist, "POWER");
1925: int iSecondPower = dSecondPower;
1926: pcpsdt->iSecondPower = iSecondPower;
1927:
1928: //- get initial state
1929:
1930: double dSecondInitActivation = SymbolParameterResolveValue(phsle, ptstr->ppist, "state_init");
1931: pcpsdt->dSecondInitActivation = dSecondInitActivation;
1932:
1933: if (dSecondPower == FLT_MAX
1934: || dSecondInitActivation == FLT_MAX)
1935: {
1936: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
1937:
1938: iResult = TSTR_PROCESSOR_ABORT;
1939: }
1940: }
1941: else
1942: {
1943: MathComponentDataStatusSet(pmcd, STATUS_UNKNOWN_TYPE, ptstr->ppist);
1944:
1945: iResult = TSTR_PROCESSOR_ABORT;
1946: }
1947: }
1948:
1949: //- if gate kinetic
1950:
1951: else if (instanceof_gate_kinetic(phsle))
1952: {
1953: if (pmcd->iStatus == 2
1954: || pmcd->iStatus == 5)
1955: {
1956: }
1957: else if (pmcd->iStatus == 3
1958: || pmcd->iStatus == 4
1959: || pmcd->iStatus == 6
1960: || pmcd->iStatus == 7)
1961: {
1962: struct DualSteadyStateParameters * pdtc
1963: = &pcpsdt->ss_parameters;
1964:
1965: struct dual_steadystate_kinetic * pdsk
1966: = ((pmcd->iStatus == 3
1967: || pmcd->iStatus == 4)
1968: ? &pdtc->first
1969: : &pdtc->second);
1970:
1971: if (pmcd->iStatus == 3
1972: || pmcd->iStatus == 6)
1973: {
1974: struct dual_steadystate_kinetic_part_a * pa = &pdsk->a;
1975:
1976: double dHasTable = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_Has_Table");
1977:
1978: int iHasTable = 0;
1979:
1980: if (dHasTable != FLT_MAX)
1981: {
1982: iHasTable = dHasTable;
1983: }
1984:
1985: if (iHasTable)
1986: {
1987: printf("warning: iHasTable has value %i\n", iHasTable);
1988:
1989: }
1990: else
1991: {
1992: //- get Multiplier
1993:
1994: double dMultiplier = SymbolParameterResolveValue(phsle, ptstr->ppist, "Multiplier");
1995:
1996: pa->dMultiplier = dMultiplier;
1997:
1998: //- get MembraneDependenceOffset
1999:
2000: double dMembraneDependenceOffset = SymbolParameterResolveValue(phsle, ptstr->ppist, "MembraneDependenceOffset");
2001:
2002: pa->dMembraneDependenceOffset = dMembraneDependenceOffset;
2003:
2004: //- get dDeNominatorOffset
2005:
2006: double dDeNominatorOffset = SymbolParameterResolveValue(phsle, ptstr->ppist, "DeNominatorOffset");
2007:
2008: pa->dDeNominatorOffset = dDeNominatorOffset;
2009:
2010: //- get MembraneOffset
2011:
2012: double dMembraneOffset = SymbolParameterResolveValue(phsle, ptstr->ppist, "MembraneOffset");
2013:
2014: pa->dMembraneOffset = dMembraneOffset;
2015:
2016: //- get TauDenormalizer
2017:
2018: double dTauDenormalizer = SymbolParameterResolveValue(phsle, ptstr->ppist, "TauDenormalizer");
2019:
2020: pa->dTauDenormalizer = dTauDenormalizer;
2021:
2022: if (dMultiplier == FLT_MAX
2023: || dMembraneDependenceOffset == FLT_MAX
2024: || dDeNominatorOffset == FLT_MAX
2025: || dMembraneOffset == FLT_MAX
2026: || dTauDenormalizer == FLT_MAX)
2027: {
2028: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
2029:
2030: iResult = TSTR_PROCESSOR_ABORT;
2031: }
2032: }
2033: }
2034: else
2035: {
2036: struct dual_steadystate_kinetic_part_b * pb = &pdsk->b;
2037:
2038: double dHasTable = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_Has_Table");
2039:
2040: int iHasTable = 0;
2041:
2042: if (dHasTable != FLT_MAX)
2043: {
2044: iHasTable = dHasTable;
2045: }
2046:
2047: if (iHasTable)
2048: {
2049: printf("warning: iHasTable has value %i\n", iHasTable);
2050:
2051: }
2052: else
2053: {
2054: //- get Multiplier
2055:
2056: double dMultiplier = SymbolParameterResolveValue(phsle, ptstr->ppist, "Multiplier");
2057:
2058: pb->dMultiplier = dMultiplier;
2059:
2060: //- get MembraneDependenceOffset
2061:
2062: double dMembraneDependenceOffset = SymbolParameterResolveValue(phsle, ptstr->ppist, "MembraneDependenceOffset");
2063:
2064: pb->dMembraneDependenceOffset = dMembraneDependenceOffset;
2065:
2066: //- get TauDenormalizer
2067:
2068: double dTauDenormalizer = SymbolParameterResolveValue(phsle, ptstr->ppist, "TauDenormalizer");
2069:
2070: pb->dTauDenormalizer = dTauDenormalizer;
2071:
2072: if (dMultiplier == FLT_MAX
2073: || dMembraneDependenceOffset == FLT_MAX
2074: || dTauDenormalizer == FLT_MAX)
2075: {
2076: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
2077:
2078: iResult = TSTR_PROCESSOR_ABORT;
2079: }
2080: }
2081: }
2082: }
2083: else if (pmcd->iStatus == 9)
2084: {
2085: struct SteppedTimeConstantParameters * pdtc
2086: = &pcpsdt->tc_parameters;
2087:
2088: double dHasTable = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_Has_Table");
2089:
2090: int iHasTable = 0;
2091:
2092: if (dHasTable != FLT_MAX)
2093: {
2094: iHasTable = dHasTable;
2095: }
2096:
2097: if (iHasTable)
2098: {
2099: printf("warning: iHasTable has value %i\n", iHasTable);
2100:
2101: }
2102: else
2103: {
2104: //- get threshold
2105:
2106: double dThreshold = SymbolParameterResolveValue(phsle, ptstr->ppist, "Threshold");
2107:
2108: pdtc->a.dThreshold = dThreshold;
2109:
2110: //- get LowTarget
2111:
2112: double dLowTarget = SymbolParameterResolveValue(phsle, ptstr->ppist, "LowTarget");
2113:
2114: pdtc->a.dLowTarget = dLowTarget;
2115:
2116: //- get HighTarget
2117:
2118: double dHighTarget = SymbolParameterResolveValue(phsle, ptstr->ppist, "HighTarget");
2119:
2120: pdtc->a.dHighTarget = dHighTarget;
2121:
2122: if (dThreshold == FLT_MAX
2123: || dLowTarget == FLT_MAX
2124: || dHighTarget == FLT_MAX)
2125: {
2126: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
2127:
2128: iResult = TSTR_PROCESSOR_ABORT;
2129: }
2130: }
2131: }
2132: else if (pmcd->iStatus == 10)
2133: {
2134: struct SteppedTimeConstantParameters * pdtc
2135: = &pcpsdt->tc_parameters;
2136:
2137: double dHasTable = SymbolParameterResolveValue(phsle, ptstr->ppist, "HH_Has_Table");
2138:
2139: int iHasTable = 0;
2140:
2141: if (dHasTable != FLT_MAX)
2142: {
2143: iHasTable = dHasTable;
2144: }
2145:
2146: if (iHasTable)
2147: {
2148: printf("warning: iHasTable has value %i\n", iHasTable);
2149:
2150: }
2151: else
2152: {
2153: //- get DeNominatorOffset
2154:
2155: double dDeNominatorOffset = SymbolParameterResolveValue(phsle, ptstr->ppist, "DeNominatorOffset");
2156:
2157: pdtc->b.dDeNominatorOffset = dDeNominatorOffset;
2158:
2159: //- get MembraneOffset
2160:
2161: double dMembraneOffset = SymbolParameterResolveValue(phsle, ptstr->ppist, "MembraneOffset");
2162:
2163: pdtc->b.dMembraneOffset = dMembraneOffset;
2164:
2165: //- get TauDenormalizer
2166:
2167: double dTauDenormalizer = SymbolParameterResolveValue(phsle, ptstr->ppist, "TauDenormalizer");
2168:
2169: pdtc->b.dTauDenormalizer = dTauDenormalizer;
2170:
2171: if (dDeNominatorOffset == FLT_MAX
2172: || dMembraneOffset == FLT_MAX
2173: || dTauDenormalizer == FLT_MAX)
2174: {
2175: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
2176:
2177: iResult = TSTR_PROCESSOR_ABORT;
2178: }
2179: }
2180: }
2181: else
2182: {
2183: MathComponentDataStatusSet(pmcd, STATUS_UNKNOWN_TYPE, ptstr->ppist);
2184:
2185: iResult = TSTR_PROCESSOR_ABORT;
2186: }
2187: }
2188:
2189: //- otherwise
2190:
2191: else
2192: {
2193: //- an error
2194:
2195: MathComponentDataStatusSet(pmcd, STATUS_UNKNOWN_TYPE, ptstr->ppist);
2196:
2197: iResult = TSTR_PROCESSOR_ABORT;
2198: }
2199:
2200: //- if no error
2201:
2202: if (pmcd->iStatus > 0)
2203: {
2204: //- increment the status to indicate what component we have processed
2205:
2206: pmcd->iStatus++;
2207:
2208: if (pmcd->iStatus == 11)
2209: {
2210: pmcd->iStatus = 1;
2211: }
2212: }
2213:
2214: //- return result
2215:
2216: return(iResult);
2217: }
2218:
2219:
2220: static
2221: int
2222: solver_mathcomponent_finalizer(struct TreespaceTraversal *ptstr, void *pvUserdata)
2223: {
2224: //- set default result : ok
2225:
2226: int iResult = TSTR_PROCESSOR_SUCCESS;
2227:
2228: //- get actual symbol
2229:
2230: struct symtab_HSolveListElement *phsle = (struct symtab_HSolveListElement *)TstrGetActual(ptstr);
2231:
2232: if (instanceof_cell(phsle))
2233: {
2234: printf("warning: cell found during solver_mathcomponent_finalizer()\n");
2235:
2236: int iBreak = 1;
2237: }
2238:
2239: //- get user data
2240:
2241: struct MathComponentData * pmcd = (struct MathComponentData *)pvUserdata;
2242:
2243: //- if segment
2244:
2245: if (instanceof_segment(phsle))
2246: {
2247: //- fill in compartment to mechanism convertor
2248:
2249: pmcd->piC2m[pmcd->iCompartment] = pmcd->iCurrentType;
2250:
2251: //- increment compartment counter
2252:
2253: pmcd->iCompartment++;
2254: }
2255:
2256: //- return result
2257:
2258: return(iResult);
2259: }
2260:
2261:
2262: static
2263: int
2264: solver_mathcomponent_processor(struct TreespaceTraversal *ptstr, void *pvUserdata)
2265: {
2266: //- set default result : ok
2267:
2268: int iResult = TSTR_PROCESSOR_SUCCESS;
2269:
2270: //- get actual symbol
2271:
2272: struct symtab_HSolveListElement *phsle = (struct symtab_HSolveListElement *)TstrGetActual(ptstr);
2273:
2274: if (instanceof_cell(phsle))
2275: {
2276: printf("warning: cell found during solver_mathcomponent_processor()\n");
2277:
2278: int iBreak = 1;
2279: }
2280:
2281: //- get user data
2282:
2283: struct MathComponentData * pmcd = (struct MathComponentData *)pvUserdata;
2284:
2285: //- get pointer to intermediary
2286:
2287: struct Heccer *pheccer = pmcd->pheccer;
2288:
2289: //- get current math component
2290:
2291: struct MathComponent * pmc = pmcd->pmc;
2292:
2293: int iType;
2294:
2295: //- if on the algorithm axis
2296:
2297: if (instanceof_algorithm_symbol(phsle))
2298: {
2299: //- ok, skip
2300:
2301: iType = -2;
2302: }
2303:
2304: //- if structure only
2305:
2306: else if (instanceof_group(phsle)
2307: || instanceof_segment(phsle)
2308: || instanceof_v_segment(phsle))
2309: {
2310: //- ok, skip
2311:
2312: iType = -2;
2313: }
2314:
2315: //- if gate and related
2316:
2317: else if (instanceof_gate_kinetic(phsle)
2318: || instanceof_h_h_gate(phsle)
2319: || instanceof_concentration_gate_kinetic(phsle)
2320: || instanceof_equation(phsle))
2321: {
2322: //- ok, skip
2323:
2324: iType = -2;
2325: }
2326:
2327: //- if simulation domain related
2328:
2329: else if (instanceof_attachment(phsle))
2330: {
2331: //- if a spikegen
2332:
2333: struct symtab_Attachment *patta = (struct symtab_Attachment *)phsle;
2334:
2335: if (AttachmentPointIsOutgoing(patta))
2336: {
2337: //- get type of math component
2338:
2339: iType = pmcd->piTypes[pmcd->iCurrentType];
2340:
2341: //- register the type in the math component array
2342:
2343: pmc->iType = iType;
2344:
2345: //- register serial
2346:
2347: int iNeurospaces = PidinStackToSerial(ptstr->ppist);
2348:
2349: pmc->iSerial = ADDRESSING_NEUROSPACES_2_HECCER(iNeurospaces);
2350:
2351: #ifdef HECCER_SOURCE_TYPING
2352:
2353: double dModelSourceType
2354: = SymbolParameterResolveValue(phsle, ptstr->ppist, "MODEL_SOURCE_TYPE");
2355:
2356: if (dModelSourceType != FLT_MAX)
2357: {
2358: pmc->iModelSourceType = dModelSourceType;
2359: }
2360: else
2361: {
2362: pmc->iModelSourceType = -1;
2363: }
2364:
2365: #endif
2366:
2367: }
2368:
2369: //- if a synapse
2370:
2371: else
2372: {
2373: //- ok, skip
2374:
2375: //! this will be taken care of during compilation of the projections.
2376:
2377: iType = -2;
2378: }
2379: }
2380:
2381: //- else
2382:
2383: else
2384: {
2385: //- default: we do not process this component
2386:
2387: int iProcess = 0;
2388:
2389: //- if passive-only mode and this is a synchan
2390:
2391: if (pheccer->ho.iOptions & HECCER_OPTION_PASSIVE_SYNCHANS)
2392: {
2393: if (instanceof_channel(phsle)
2394: && SymbolHasEquation(phsle, ptstr->ppist))
2395: {
2396: //- ok, process
2397:
2398: iProcess = 1;
2399: }
2400: }
2401:
2402: //- else, active mode
2403:
2404: else
2405: {
2406: //- ok, process everything
2407:
2408: iProcess = 1;
2409: }
2410:
2411: //- if we must process this component
2412:
2413: if (iProcess)
2414: {
2415: //- get type of math component
2416:
2417: iType = pmcd->piTypes[pmcd->iCurrentType];
2418:
2419: //- register the type in the math component array
2420:
2421: pmc->iType = iType;
2422:
2423: //- register serial
2424:
2425: int iNeurospaces = PidinStackToSerial(ptstr->ppist);
2426:
2427: pmc->iSerial = ADDRESSING_NEUROSPACES_2_HECCER(iNeurospaces);
2428:
2429: #ifdef HECCER_SOURCE_TYPING
2430:
2431: double dModelSourceType
2432: = SymbolParameterResolveValue(phsle, ptstr->ppist, "MODEL_SOURCE_TYPE");
2433:
2434: if (dModelSourceType != FLT_MAX)
2435: {
2436: pmc->iModelSourceType = dModelSourceType;
2437: }
2438: else
2439: {
2440: pmc->iModelSourceType = -1;
2441: }
2442:
2443: #endif
2444:
2445: }
2446: else
2447: {
2448: iType = -2;
2449: }
2450: }
2451:
2452: //- depending on the type
2453:
2454: switch (iType)
2455: {
2456: //- for a channel
2457:
2458: case MATH_TYPE_ChannelAct:
2459: case MATH_TYPE_ChannelActConc:
2460: case MATH_TYPE_ChannelActInact:
2461: case MATH_TYPE_ChannelPersistentSteadyStateDualTau:
2462: case MATH_TYPE_ChannelPersistentSteadyStateTau:
2463: case MATH_TYPE_ChannelSpringMass:
2464: case MATH_TYPE_ChannelSteadyStateSteppedTau:
2465: {
2466: //- get maximal conductance
2467:
2468: double dMaximalConductance = SymbolParameterResolveScaledValue(phsle, ptstr->ppist, "G_MAX");
2469:
2470: //- get reversal potential
2471:
2472: double dReversalPotential = SymbolParameterResolveValue(phsle, ptstr->ppist, "Erev");
2473:
2474: if (dMaximalConductance == FLT_MAX
2475: || dReversalPotential == FLT_MAX)
2476: {
2477: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
2478:
2479: iResult = TSTR_PROCESSOR_ABORT;
2480: }
2481:
2482: //- determine link with math component that computes the
2483: //- reversal potential, if any
2484:
2485: int iReversalPotential = -1;
2486:
2487: if (SymbolHasNernstErev(phsle, ptstr->ppist))
2488: {
2489: //- currently the nernst intermediary always comes after the channel
2490:
2491: //! this can be dependent on the other functions present, notably mgblocking.
2492:
2493: iReversalPotential = pmc->iSerial + 1;
2494: }
2495:
2496: //- set values
2497:
2498: if (iType == MATH_TYPE_ChannelAct)
2499: {
2500: struct ChannelAct * pca = (struct ChannelAct *)pmc;
2501:
2502: pca->dMaximalConductance = dMaximalConductance;
2503:
2504: pca->dReversalPotential = dReversalPotential;
2505:
2506: pca->iReversalPotential = iReversalPotential;
2507:
2508: pca->iPool = -1;
2509: }
2510: else if (iType == MATH_TYPE_ChannelActInact)
2511: {
2512: struct ChannelActInact * pcai = (struct ChannelActInact *)pmc;
2513:
2514: pcai->dMaximalConductance = dMaximalConductance;
2515:
2516: pcai->dReversalPotential = dReversalPotential;
2517:
2518: pcai->iReversalPotential = iReversalPotential;
2519:
2520: pcai->iPool = -1;
2521: }
2522: else if (iType == MATH_TYPE_ChannelPersistentSteadyStateDualTau)
2523: {
2524: struct ChannelPersistentSteadyStateDualTau * pcpsdt = (struct ChannelPersistentSteadyStateDualTau *)pmc;
2525:
2526: pcpsdt->dMaximalConductance = dMaximalConductance;
2527:
2528: pcpsdt->dReversalPotential = dReversalPotential;
2529:
2530: pcpsdt->iReversalPotential = iReversalPotential;
2531:
2532: pcpsdt->iPool = -1;
2533: }
2534: else if (iType == MATH_TYPE_ChannelPersistentSteadyStateTau)
2535: {
2536: struct ChannelPersistentSteadyStateTau * pcpst = (struct ChannelPersistentSteadyStateTau *)pmc;
2537:
2538: pcpst->dMaximalConductance = dMaximalConductance;
2539:
2540: pcpst->dReversalPotential = dReversalPotential;
2541:
2542: pcpst->iReversalPotential = iReversalPotential;
2543:
2544: pcpst->iPool = -1;
2545: }
2546: else if (iType == MATH_TYPE_ChannelSteadyStateSteppedTau)
2547: {
2548: struct ChannelSteadyStateSteppedTau * pcsst = (struct ChannelSteadyStateSteppedTau *)pmc;
2549:
2550: pcsst->dMaximalConductance = dMaximalConductance;
2551:
2552: pcsst->dReversalPotential = dReversalPotential;
2553:
2554: pcsst->iReversalPotential = iReversalPotential;
2555:
2556: pcsst->iPool = -1;
2557: }
2558: else if (iType == MATH_TYPE_ChannelSpringMass)
2559: {
2560: struct ChannelSpringMass * pcsm = (struct ChannelSpringMass *)pmc;
2561:
2562: pcsm->dMaximalConductance = dMaximalConductance;
2563:
2564: pcsm->dReversalPotential = dReversalPotential;
2565:
2566: pcsm->iReversalPotential = iReversalPotential;
2567:
2568: pcsm->iPool = -1;
2569:
2570: //- get endogenous activation frequency
2571:
2572: double dFrequency = SymbolParameterResolveValue(phsle, ptstr->ppist, "FREQUENCY");
2573:
2574: //t this case should actually be handled by neurospaces ?
2575:
2576: if (dFrequency == FLT_MAX)
2577: {
2578: dFrequency = 0;
2579: }
2580:
2581: pcsm->dFrequency = dFrequency;
2582:
2583: //t not sure about this one
2584: //t
2585: //t I think, because it is a low level component for I/O to the model, the setting
2586: //t should not be done over neurospaces, but over ssp parameter settings.
2587:
2588: pcsm->pdEventTimes = NULL;
2589: }
2590: else if (iType == MATH_TYPE_ChannelActConc)
2591: {
2592: struct ChannelActConc * pcac = (struct ChannelActConc *)pmc;
2593:
2594: pcac->dMaximalConductance = dMaximalConductance;
2595:
2596: pcac->dReversalPotential = dReversalPotential;
2597:
2598: pcac->iReversalPotential = iReversalPotential;
2599:
2600: pcac->iPool = -1;
2601:
2602: //m contributes to this concentration pool, -1 for none, boolean indicator only.
2603:
2604: struct PidinStack *ppistPool
2605: = SymbolResolveInput(phsle, ptstr->ppist, "concen", 0);
2606:
2607: if (ppistPool)
2608: {
2609: /* //t this is a hack to get things to work right now, */
2610: /* //t see TODOs in neurospaces */
2611:
2612: /* //t this hack will not work when components are in different groups or so */
2613:
2614: /* int iSerialDifference */
2615: /* = piolPool->hsle.smapPrincipal.iParent - phsle->smapPrincipal.iParent; */
2616:
2617: int iPool = PidinStackToSerial(ppistPool);
2618:
2619: pcac->pac.ca.iActivator = ADDRESSING_NEUROSPACES_2_HECCER(iPool);
2620:
2621: PidinStackFree(ppistPool);
2622:
2623: }
2624: else
2625: {
2626: pcac->pac.ca.iActivator = -1;
2627: }
2628: }
2629: else
2630: {
2631: MathComponentDataStatusSet(pmcd, STATUS_UNKNOWN_TYPE, ptstr->ppist);
2632:
2633: iResult = TSTR_PROCESSOR_ABORT;
2634: }
2635:
2636: //- if no errors yet
2637:
2638: if (pmcd->iStatus > 0)
2639: {
2640: //! push and pop, the quick hack
2641:
2642: int iStatus = pmcd->iStatus;
2643:
2644: pmcd->iStatus = 1;
2645:
2646: //- if traverse channel descendants
2647:
2648: TreespaceTraversalProcessor * pfProcesor = Type2Processor(iType);
2649:
2650: struct TreespaceTraversal * ptstrChannel
2651: = TstrNew
2652: (ptstr->ppist,
2653: NULL,
2654: NULL,
2655: pfProcesor,
2656: (void *)pmcd,
2657: ptstr->pfFinalizer,
2658: ptstr->pvFinalizer);
2659:
2660: iResult = TstrGo(ptstrChannel, phsle);
2661:
2662: if (iResult == 1)
2663: {
2664: pmcd->iStatus = iStatus;
2665:
2666: iResult = TSTR_PROCESSOR_FAILURE;
2667: }
2668: else
2669: {
2670: MathComponentDataStatusSet(pmcd, STATUS_UNKNOWN_ERROR, ptstr->ppist);
2671:
2672: iResult = TSTR_PROCESSOR_ABORT;
2673: }
2674:
2675: TstrDelete(ptstrChannel);
2676:
2677: //- advance to the next math component
2678:
2679: pmcd->pmc = MathComponentNext(pmcd->pmc);
2680:
2681: pmcd->iCurrentType++;
2682:
2683: pmc = pmcd->pmc;
2684: }
2685:
2686: //- if there is a nernst function
2687:
2688: int iFunctions = 1;
2689:
2690: if (SymbolHasNernstErev(phsle, ptstr->ppist))
2691: {
2692: struct InternalNernst * pin = (struct InternalNernst *)pmc;
2693:
2694: int iNernst = PidinStackToSerial(ptstr->ppist);
2695:
2696: iNernst = ADDRESSING_NEUROSPACES_2_HECCER(iNernst) + iFunctions;
2697:
2698: //- set type and serial
2699:
2700: pin->mc.iType = MATH_TYPE_InternalNernst;
2701: pin->mc.iSerial = iNernst;
2702:
2703: #ifdef HECCER_SOURCE_TYPING
2704:
2705: double dModelSourceType
2706: = SymbolParameterResolveValue(phsle, ptstr->ppist, "MODEL_SOURCE_TYPE");
2707:
2708: if (dModelSourceType != FLT_MAX)
2709: {
2710: pin->mc.iModelSourceType = dModelSourceType;
2711: }
2712: else
2713: {
2714: pin->mc.iModelSourceType = -1;
2715: }
2716:
2717: #endif
2718:
2719: //- get Erev parameter
2720:
2721: struct symtab_Parameters *pparErev
2722: = SymbolGetParameter(phsle, ptstr->ppist, "Erev");
2723:
2724: //- get nernst function
2725:
2726: struct symtab_Function *pfunNernst
2727: = ParameterGetFunction(pparErev);
2728:
2729: //- fetch parameters
2730:
2731: struct symtab_Parameters *pparCIn
2732: = FunctionGetParameter(pfunNernst, "Cin");
2733: struct symtab_Parameters *pparCOut
2734: = FunctionGetParameter(pfunNernst, "Cout");
2735: struct symtab_Parameters *pparValency
2736: = FunctionGetParameter(pfunNernst, "valency");
2737: struct symtab_Parameters *pparT
2738: = FunctionGetParameter(pfunNernst, "T");
2739:
2740: if (!pparCIn
2741: || !pparCOut
2742: || !pparValency
2743: || !pparT)
2744: {
2745: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
2746:
2747: iResult = TSTR_PROCESSOR_ABORT;
2748:
2749: break;
2750: }
2751:
2752: //- calculate parameter values
2753:
2754: double dCIn = ParameterResolveValue(pparCIn, ptstr->ppist);
2755: double dCOut = ParameterResolveValue(pparCOut, ptstr->ppist);
2756: double dValency = ParameterResolveValue(pparValency, ptstr->ppist);
2757: double dT = ParameterResolveValue(pparT, ptstr->ppist);
2758:
2759: if (dCIn == FLT_MAX
2760: || dCOut == FLT_MAX
2761: || dValency == FLT_MAX
2762: || dT == FLT_MAX)
2763: {
2764: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
2765:
2766: iResult = TSTR_PROCESSOR_ABORT;
2767:
2768: break;
2769: }
2770:
2771: /* SI units */
2772: #define GAS_CONSTANT 8.314 /* (V * C)/(deg K * mol) */
2773: #define FARADAY 9.6487e4 /* C / mol */
2774: #define ZERO_CELSIUS 273.15 /* deg */
2775: #define R_OVER_F 8.6171458e-5 /* volt/deg */
2776: #define F_OVER_R 1.1605364e4 /* deg/volt */
2777:
2778: //- calculate (genesis style) nernst constant
2779:
2780: double dConstant = R_OVER_F * (dT + ZERO_CELSIUS) / dValency;
2781:
2782: //- fill in values
2783:
2784: pin->dConstant = dConstant;
2785: pin->dExternal = dCOut;
2786:
2787: //! neurospaces contains support to evaluate simple functions
2788:
2789: pin->dInitPotential = SymbolParameterResolveValue(phsle, ptstr->ppist, "Erev");
2790:
2791: //- find concentration that determines the nernst potential
2792:
2793: struct symtab_HSolveListElement *phslePool
2794: = SymbolResolveParameterFunctionalInput
2795: (phsle, ptstr->ppist, "Erev", "Cin", 0);
2796:
2797: //- if found
2798:
2799: if (phslePool)
2800: {
2801: if (!instanceof_pool(phslePool))
2802: {
2803: MathComponentDataStatusSet(pmcd, STATUS_NON_POOL_FOR_NERNST, ptstr->ppist);
2804:
2805: iResult = TSTR_PROCESSOR_ABORT;
2806:
2807: break;
2808: }
2809:
2810: //t this is a hack to get things to work right now,
2811: //t see TODOs in neurospaces
2812:
2813: //t this hack will not work when components are in different groups or so
2814:
2815: int iSerialDifference
2816: = phslePool->smapPrincipal.iParent - phsle->smapPrincipal.iParent;
2817:
2818: int iPool = PidinStackToSerial(ptstr->ppist) + iSerialDifference;
2819:
2820: iPool = ADDRESSING_NEUROSPACES_2_HECCER(iPool);
2821:
2822: pin->iInternal = iPool;
2823:
2824: //- register the channel as a flux contributor
2825:
2826: pmcd->ppiConnectors[pmcd->iConnectors][0] = iPool;
2827: pmcd->ppiConnectors[pmcd->iConnectors][1] = iNernst;
2828:
2829: pmcd->iConnectors++;
2830: }
2831: else
2832: {
2833: //t fallback to constant nernst, requires changes in the typer
2834:
2835: MathComponentDataStatusSet(pmcd, STATUS_CONSTANT_NERNST, ptstr->ppist);
2836:
2837: iResult = TSTR_PROCESSOR_ABORT;
2838:
2839: break;
2840: }
2841:
2842: //- advance to the next math component
2843:
2844: pmcd->pmc = MathComponentNext(pmcd->pmc);
2845:
2846: pmcd->iCurrentType++;
2847:
2848: pmc = pmcd->pmc;
2849:
2850: iFunctions++;
2851: }
2852:
2853: //t mgblocking
2854:
2855: break;
2856: }
2857:
2858: //- for an exponential
2859:
2860: case MATH_TYPE_ExponentialDecay:
2861: {
2862: //- get math component data
2863:
2864: struct ExponentialDecay * pexdec
2865: = (struct ExponentialDecay *)pmc;
2866:
2867: //- get initial value
2868:
2869: double dInitValue = SymbolParameterResolveValue(phsle, ptstr->ppist, "concen_init");
2870:
2871: //- get beta
2872:
2873: double dBeta = SymbolParameterResolveScaledValue(phsle, ptstr->ppist, "BETA");
2874:
2875: //- get steady state
2876:
2877: double dSteadyState = SymbolParameterResolveValue(phsle, ptstr->ppist, "BASE");
2878:
2879: //- get tau
2880:
2881: double dTau = SymbolParameterResolveValue(phsle, ptstr->ppist, "TAU");
2882:
2883: if (dInitValue == FLT_MAX
2884: || dBeta == FLT_MAX
2885: || dSteadyState == FLT_MAX
2886: || dTau == FLT_MAX)
2887: {
2888: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
2889:
2890: iResult = TSTR_PROCESSOR_ABORT;
2891: }
2892:
2893: if (dInitValue == 0
2894: || dBeta == 0)
2895: {
2896: MathComponentDataStatusSet(pmcd, STATUS_ILLEGAL_PARAMETER_VALUES, ptstr->ppist);
2897:
2898: iResult = TSTR_PROCESSOR_ABORT;
2899:
2900: fprintf(stdout, "STATUS_ILLEGAL_PARAMETER_VALUES for the following:\n");
2901:
2902: PidinStackTo_stdout(ptstr->ppist);
2903: }
2904:
2905: if (1 / dInitValue == 0
2906: || 1 / dBeta == 0)
2907: {
2908: MathComponentDataStatusSet(pmcd, STATUS_ILLEGAL_PARAMETER_VALUES, ptstr->ppist);
2909:
2910: iResult = TSTR_PROCESSOR_ABORT;
2911:
2912: fprintf(stdout, "STATUS_ILLEGAL_PARAMETER_VALUES for the following:\n");
2913:
2914: PidinStackTo_stdout(ptstr->ppist);
2915: }
2916:
2917: //- set values
2918:
2919: pexdec->dInitValue = dInitValue;
2920: pexdec->dBeta = dBeta;
2921: pexdec->dSteadyState = dSteadyState;
2922: pexdec->dTau = dTau;
2923:
2924: //- find contributing channels
2925:
2926: int iInput;
2927:
2928: for (iInput = 0 ; iInput < EXPONENTIALDECAY_CONTRIBUTORS ; iInput++)
2929: {
2930: struct PidinStack *ppistExternal
2931: = SymbolResolveInput(phsle, ptstr->ppist, "I", iInput);
2932:
2933: if (ppistExternal)
2934: {
2935: struct symtab_HSolveListElement *phsleExternal
2936: = PidinStackLookupTopSymbol(ppistExternal);
2937:
2938: if (!instanceof_channel(phsleExternal))
2939: {
2940: MathComponentDataStatusSet(pmcd, STATUS_NON_CHANNEL_OUTPUTS_IK, ptstr->ppist);
2941:
2942: iResult = TSTR_PROCESSOR_ABORT;
2943:
2944: break;
2945: }
2946:
2947: /* //t this is a hack to get things to work right now, */
2948: /* //t see TODOs in neurospaces */
2949:
2950: /* //t this hack will not work when components are in different groups or so */
2951:
2952: /* int iSerialDifference */
2953: /* = piolExternal->hsle.smapPrincipal.iParent - phsle->smapPrincipal.iParent; */
2954:
2955: int iChannel = PidinStackToSerial(ppistExternal);
2956: int iPool = PidinStackToSerial(ptstr->ppist);
2957:
2958: iChannel = ADDRESSING_NEUROSPACES_2_HECCER(iChannel);
2959: iPool = ADDRESSING_NEUROSPACES_2_HECCER(iPool);
2960:
2961: pexdec->piExternal[iInput] = iChannel;
2962:
2963: //- register the channel as a flux contributor
2964:
2965: pmcd->ppiConnectors[pmcd->iConnectors][0] = iChannel;
2966: pmcd->ppiConnectors[pmcd->iConnectors][1] = iPool;
2967:
2968: pmcd->iConnectors++;
2969:
2970: PidinStackFree(ppistExternal);
2971:
2972: }
2973: else
2974: {
2975: pexdec->piExternal[iInput] = -1;
2976: }
2977: }
2978:
2979: //- check for to many contributors
2980:
2981: struct PidinStack *ppistExternal
2982: = SymbolResolveInput(phsle, ptstr->ppist, "I", iInput);
2983:
2984: if (ppistExternal)
2985: {
2986: MathComponentDataStatusSet(pmcd, STATUS_MANY_CHANNELS, ptstr->ppist);
2987:
2988: iResult = TSTR_PROCESSOR_ABORT;
2989:
2990: PidinStackFree(ppistExternal);
2991: }
2992:
2993: //- advance to the next math component
2994:
2995: pmcd->pmc = MathComponentNext(pmcd->pmc);
2996:
2997: pmcd->iCurrentType++;
2998:
2999: pmc = pmcd->pmc;
3000:
3001: break;
3002: }
3003:
3004: //- for a spike generator
3005:
3006: case MATH_TYPE_SpikeGenerator:
3007: {
3008: //t for spikegens: initialize struct SpikeGenerator
3009:
3010: //- get math component data
3011:
3012: struct SpikeGenerator * psg
3013: = (struct SpikeGenerator *)pmc;
3014:
3015: //- get refractory time
3016:
3017: double dRefractory = SymbolParameterResolveValue(phsle, ptstr->ppist, "REFRACTORY");
3018:
3019: //- get spiking threshold
3020:
3021: double dThreshold = SymbolParameterResolveValue(phsle, ptstr->ppist, "THRESHOLD");
3022:
3023: //- get reset value, FLT_MAX for none
3024:
3025: double dReset = SymbolParameterResolveValue(phsle, ptstr->ppist, "RESET");
3026:
3027: //- unset table in event distributor with targets, will be
3028: //- filled when projections are compiled
3029:
3030: int iTable = INT_MAX;
3031:
3032: if (dRefractory == FLT_MAX
3033: || dThreshold == FLT_MAX)
3034: {
3035: MathComponentDataStatusSet(pmcd, STATUS_UNRESOLVABLE_PARAMETERS, ptstr->ppist);
3036:
3037: iResult = TSTR_PROCESSOR_ABORT;
3038: }
3039:
3040: if (dRefractory <= 0)
3041: {
3042: MathComponentDataStatusSet(pmcd, STATUS_ILLEGAL_PARAMETER_VALUES, ptstr->ppist);
3043:
3044: iResult = TSTR_PROCESSOR_ABORT;
3045:
3046: fprintf(stdout, "STATUS_ILLEGAL_PARAMETER_VALUES for the following:\n");
3047:
3048: PidinStackTo_stdout(ptstr->ppist);
3049: }
3050:
3051: //- set values
3052:
3053: psg->dRefractory = dRefractory;
3054: psg->dThreshold = dThreshold;
3055: psg->dReset = dReset;
3056: psg->iTable = iTable;
3057:
3058: //- advance to the next math component
3059:
3060: pmcd->pmc = MathComponentNext(pmcd->pmc);
3061:
3062: pmcd->iCurrentType++;
3063:
3064: pmc = pmcd->pmc;
3065:
3066: break;
3067: }
3068:
3069: //- for skipped components
3070:
3071: case -2:
3072: {
3073: //- nothing registered, nothing done
3074:
3075: break;
3076: }
3077:
3078: //- otherwise
3079:
3080: default:
3081: {
3082: //- type consistency error
3083:
3084: MathComponentDataStatusSet(pmcd, STATUS_CONSISTENCY, ptstr->ppist);
3085:
3086: iResult = TSTR_PROCESSOR_ABORT;
3087:
3088: break;
3089: }
3090: }
3091:
3092: //- return result
3093:
3094: return(iResult);
3095: }
3096:
3097:
3098: static
3099: int
3100: solver_mathcomponent_typer(struct TreespaceTraversal *ptstr, void *pvUserdata)
3101: {
3102: //- set default result : ok
3103:
3104: int iResult = TSTR_PROCESSOR_SUCCESS;
3105:
3106: //- get actual symbol
3107:
3108: struct symtab_HSolveListElement *phsle = (struct symtab_HSolveListElement *)TstrGetActual(ptstr);
3109:
3110: if (instanceof_cell(phsle))
3111: {
3112: printf("warning: cell found during solver_mathcomponent_finalizer()\n");
3113:
3114: int iBreak = 1;
3115: }
3116:
3117: //- get user data
3118:
3119: struct MathComponentData * pmcd = (struct MathComponentData *)pvUserdata;
3120:
3121: //- get pointer to intermediary
3122:
3123: struct Heccer *pheccer = pmcd->pheccer;
3124:
3125: //- set default type : error
3126:
3127: int iType = INT_MAX;
3128:
3129: //- if on the algorithm axis
3130:
3131: if (instanceof_algorithm_symbol(phsle))
3132: {
3133: //- ok, skip
3134:
3135: iType = -2;
3136: }
3137:
3138: //- if structure only
3139:
3140: else if (instanceof_group(phsle)
3141: || instanceof_segment(phsle)
3142: || instanceof_v_segment(phsle))
3143: {
3144: //- ok, skip
3145:
3146: iType = -2;
3147: }
3148:
3149: //- if gate and related
3150:
3151: else if (instanceof_gate_kinetic(phsle)
3152: || instanceof_h_h_gate(phsle)
3153: || instanceof_concentration_gate_kinetic(phsle)
3154: || instanceof_equation(phsle))
3155: {
3156: //- ok, skip
3157:
3158: iType = -2;
3159: }
3160:
3161: //- if simulation domain related
3162:
3163: else if (instanceof_attachment(phsle))
3164: {
3165: //- if a spikegen
3166:
3167: struct symtab_Attachment *patta = (struct symtab_Attachment *)phsle;
3168:
3169: if (AttachmentPointIsOutgoing(patta))
3170: {
3171: //- ok, register
3172:
3173: iType = MATH_TYPE_SpikeGenerator;
3174: }
3175:
3176: //- if a synapse
3177:
3178: else
3179: {
3180: //- ok, skip
3181:
3182: //! this will be taken care of during compilation of the projections.
3183:
3184: iType = -2;
3185: }
3186: }
3187:
3188: //- pool
3189:
3190: else if (instanceof_pool(phsle))
3191: {
3192: //- if passive-only mode
3193:
3194: if (pheccer->ho.iOptions & HECCER_OPTION_PASSIVE_SYNCHANS)
3195: {
3196: //- ok, skip
3197:
3198: iType = -2;
3199: }
3200:
3201: //- if active mode
3202:
3203: else
3204: {
3205: //- ok, register
3206:
3207: iType = MATH_TYPE_ExponentialDecay;
3208: }
3209: }
3210:
3211: //- channel
3212:
3213: else if (instanceof_channel(phsle))
3214: {
3215: //t clearly there should be global filter for this: given a
3216: //t component, should we process it or not ? This filter should
3217: //t then be used by the other functions too, to see what must go
3218: //t to the intermediary.
3219:
3220: //- default: we do not process channels
3221:
3222: int iProcess = 0;
3223:
3224: //- if passive-only mode and this is a synchan
3225:
3226: if (pheccer->ho.iOptions & HECCER_OPTION_PASSIVE_SYNCHANS)
3227: {
3228: if (SymbolHasEquation(phsle, ptstr->ppist))
3229: {
3230: //- ok, process
3231:
3232: iProcess = 1;
3233: }
3234: }
3235:
3236: //- else, active mode
3237:
3238: else
3239: {
3240: //- ok, process everything
3241:
3242: iProcess = 1;
3243: }
3244:
3245: //- if we must process this channel
3246:
3247: if (iProcess)
3248: {
3249: struct symtab_Parameters *pparType
3250: = SymbolFindParameter(phsle, ptstr->ppist, "CHANNEL_TYPE");
3251:
3252: if (pparType
3253: || SymbolHasEquation(phsle, ptstr->ppist))
3254: {
3255: char *pcType = pparType ? ParameterGetString(pparType) : NULL;
3256:
3257: //- check if channel has an exponential equation
3258:
3259: int iEquation = SymbolHasEquation(phsle, ptstr->ppist);
3260:
3261: //- if channel has multiple concentration dependencies
3262:
3263: struct PidinStack *ppistPool1
3264: = SymbolResolveInput(phsle, ptstr->ppist, "concen", 1);
3265:
3266: if (ppistPool1)
3267: {
3268: //- abort the traversal
3269:
3270: MathComponentDataStatusSet(pmcd, STATUS_MANY_POOLS, ptstr->ppist);
3271:
3272: iResult = TSTR_PROCESSOR_ABORT;
3273:
3274: PidinStackFree(ppistPool1);
3275:
3276: }
3277:
3278: if (pcType && strncasecmp(pcType, "ChannelPersistentSteadyStateTau", strlen("ChannelPersistentSteadyStateTau")) == 0)
3279: {
3280: //t MATH_TYPE_ChannelPersistentSteadyStateTau: steady state with two parts (km)
3281:
3282: iType = MATH_TYPE_ChannelPersistentSteadyStateTau;
3283: }
3284: else if (pcType && strncasecmp(pcType, "ChannelPersistentSteadyStateDualTau", strlen("ChannelPersistentSteadyStateDualTau")) == 0)
3285: {
3286: //- MATH_TYPE_ChannelPersistentSteadyStateDualTau: tau with two parts ? (kh)
3287:
3288: iType = MATH_TYPE_ChannelPersistentSteadyStateDualTau;
3289: }
3290: else if (pcType && strncasecmp(pcType, "ChannelSteadyStateSteppedTau", strlen("ChannelSteadyStateSteppedTau")) == 0)
3291: {
3292: //t MATH_TYPE_ChannelSteadyStateSteppedTau: steady state with 2x2 parts, tau with 2 parts (kdr)
3293:
3294: iType = MATH_TYPE_ChannelSteadyStateSteppedTau;
3295: }
3296: else if (pcType && strncasecmp(pcType, "ChannelActConc", strlen("ChannelActConc")) == 0)
3297: {
3298: //t when the concen was not bound, the test above fails.
3299: //t need a separate name for the concen gate or so
3300:
3301: iType = MATH_TYPE_ChannelActConc;
3302: }
3303: else if (pcType && strncasecmp(pcType, "ChannelActInact", strlen("ChannelActInact")) == 0)
3304: {
3305: //t when the concen was not bound, the test above fails.
3306: //t need a separate name for the concen gate or so
3307:
3308: iType = MATH_TYPE_ChannelActInact;
3309: }
3310: else if (pcType && strncasecmp(pcType, "ChannelAct", strlen("ChannelAct")) == 0)
3311: {
3312: //- MATH_TYPE_ChannelAct: only one gate (nap)
3313:
3314: iType = MATH_TYPE_ChannelAct;
3315: }
3316: else
3317: {
3318: //- if the channel has an exponential equation
3319:
3320: if (iEquation)
3321: {
3322: //- type is springmass channel
3323:
3324: iType = MATH_TYPE_ChannelSpringMass;
3325: }
3326: else
3327: {
3328: //- abort the traversal
3329:
3330: HeccerError
3331: (pheccer,
3332: NULL,
3333: "solver_mathcomponent_typer() cannot determine channel type for %s (is the CHANNEL_TYPE parameter valid ?).",
3334: SymbolGetName(phsle));
3335:
3336: MathComponentDataStatusSet(pmcd, STATUS_UNKNOWN_CHANNEL_TYPE1, ptstr->ppist);
3337:
3338: iResult = TSTR_PROCESSOR_ABORT;
3339: }
3340: }
3341:
3342: //- if the channel has a nernst function
3343:
3344: //t need a separate loop for registering the type or so.
3345:
3346: if (SymbolHasNernstErev(phsle, ptstr->ppist))
3347: {
3348: if (!MathComponentDataTypeRegister(pmcd, iType, ptstr->ppist))
3349: {
3350: iResult = TSTR_PROCESSOR_ABORT;
3351: }
3352:
3353: //t differentiate between internal and external nernst,
3354: //t possibly also differentiate with constant nernst
3355:
3356: iType = MATH_TYPE_InternalNernst;
3357: }
3358:
3359: //t MATH_TYPE_MGBlocker
3360:
3361: //t check for attachments (synchans)
3362: }
3363: else
3364: {
3365: //- abort the traversal
3366:
3367: HeccerError
3368: (pheccer,
3369: NULL,
3370: "solver_mathcomponent_typer() cannot determine channel type for %s (is the CHANNEL_TYPE parameter present ?).",
3371: SymbolGetName(phsle));
3372:
3373: MathComponentDataStatusSet(pmcd, STATUS_UNKNOWN_CHANNEL_TYPE3, ptstr->ppist);
3374:
3375: iResult = TSTR_PROCESSOR_ABORT;
3376:
3377: //t deal with channels that are linked with a table
3378: //t generated externally (using genesis2)
3379: }
3380: }
3381: else
3382: {
3383: iType = -2;
3384: }
3385: }
3386:
3387: //- register type
3388:
3389: if (!MathComponentDataTypeRegister(pmcd, iType, ptstr->ppist))
3390: {
3391: iResult = TSTR_PROCESSOR_ABORT;
3392: }
3393:
3394: //- return result
3395:
3396: return(iResult);
3397: }
3398:
3399:
3400: static int cellsolver_getmathcomponents(struct Heccer *pheccer, struct TranslationService *pts)
3401: {
3402: //- set default result : ok
3403:
3404: int iResult = TRUE;
3405:
3406: //- allocate pidin stack pointing to root
3407:
3408: struct PidinStack *ppistRoot = pts->ptsd->ppistRoot;
3409:
3410: struct symtab_HSolveListElement *phsleRoot = pts->ptsd->phsleRoot;
3411:
3412: //- get model context to solve
3413:
3414: struct PidinStack *ppistModel
3415: = SymbolPrincipalSerial2Context(phsleRoot, ppistRoot, pts->ptsd->iModel);
3416:
3417: if (ppistModel)
3418: {
3419: //- lookup symbol
3420:
3421: struct symtab_HSolveListElement *phsleModel
3422: = PidinStackLookupTopSymbol(ppistModel);
3423:
3424: //- determine size of math component array
3425:
3426: struct MathComponentData mcd = {
3427:
3428: //m solution engine
3429:
3430: pheccer,
3431:
3432: //m compartment number
3433:
3434: 0,
3435:
3436: //m compartment 2 mechanism convertor
3437:
3438: NULL,
3439:
3440: //m current compartment
3441:
3442: NULL,
3443:
3444: NULL,
3445:
3446: //m array of all math component types
3447:
3448: 0,
3449:
3450: 0,
3451:
3452: NULL,
3453:
3454: //m current mathcomponent
3455:
3456: NULL,
3457:
3458: //m number of spikegens
3459:
3460: 0,
3461:
3462: //m operational status: positive is positive, negative is negative (error)
3463:
3464: 1,
3465:
3466: "",
3467:
3468: "",
3469:
3470: //m channels that contribute to a pool
3471:
3472: //! to set the iPool boolean indicator
3473:
3474: 0,
3475:
3476: NULL,
3477:
3478: };
3479:
3480: //t should try to get rid of this allocation somehow
3481:
3482: #define MAXIMUM_NUMBER_OF_CHANNEL_CONTRIBUTORS 100000
3483:
3484: {
3485: mcd.ppiConnectors = (int **)calloc(MAXIMUM_NUMBER_OF_CHANNEL_CONTRIBUTORS, sizeof(int *));
3486:
3487: int i;
3488:
3489: for (i = 0 ; i < MAXIMUM_NUMBER_OF_CHANNEL_CONTRIBUTORS ; i++)
3490: {
3491: mcd.ppiConnectors[i] = (int *)calloc(2, sizeof(int));
3492: }
3493: }
3494:
3495: //- get descendants
3496:
3497: int iDescendants = SymbolGetPrincipalNumOfSuccessors(phsleModel);
3498:
3499: //- allow maximally this number of functions
3500:
3501: //t to remove this 'opportunistic hack', neurospaces should
3502: //t (1) serve the model a bit cleaner,
3503: //t (2) by incorporating the functions into the symbol hierarchy.
3504: //t See relevant comments in symbol hierarchy.
3505:
3506: #define MAXIMUM_NUMBER_OF_FUNCTIONS 100000
3507:
3508: //! + 1 for '-1' terminator
3509:
3510: iDescendants += MAXIMUM_NUMBER_OF_FUNCTIONS + 1;
3511:
3512: //- allocate types array
3513:
3514: mcd.iDescendants = iDescendants;
3515:
3516: mcd.piTypes = (int *)calloc(iDescendants, sizeof(int));
3517:
3518: //- set compartment 2 mechanism convertor
3519:
3520: mcd.piC2m = pheccer->inter.piC2m;
3521:
3522: //- traverse solved components, register types
3523:
3524: struct TreespaceTraversal *ptstr
3525: = TstrNew
3526: (ppistModel,
3527: NULL,
3528: NULL,
3529: solver_mathcomponent_typer,
3530: (void *)&mcd,
3531: NULL,
3532: NULL);
3533:
3534: iResult = TstrGo(ptstr, phsleModel);
3535:
3536: if (mcd.iStatus > 0)
3537: {
3538: //- if there were mechanisms found
3539:
3540: if (mcd.iCurrentType > 0)
3541: {
3542: //- register type terminator
3543:
3544: if (MathComponentDataTypeRegister(&mcd, -1, ptstr->ppist))
3545: {
3546: //- allocate math component array
3547:
3548: struct MathComponentArray * pmca
3549: = (struct MathComponentArray *)calloc(1, sizeof(struct MathComponentArray));
3550:
3551: if (pmca)
3552: {
3553: if (MathComponentArrayCallocData(pmca, mcd.piTypes))
3554: {
3555: //- register math component array with the intermediary
3556:
3557: pheccer->inter.pmca = pmca;
3558:
3559: //- traverse solved components, initialize intermediary
3560:
3561: mcd.iCurrentType = 0;
3562:
3563: mcd.pmc = pmca->pmc;
3564:
3565: //t not sure if recycling is still allowed ...
3566:
3567: ptstr->iStatus = TSTR_STATUS_NEW;
3568: ptstr->pfProcessor = solver_mathcomponent_processor;
3569: ptstr->pfFinalizer = solver_mathcomponent_finalizer;
3570: ptstr->pvFinalizer = (void *)&mcd;
3571:
3572: iResult = TstrGo(ptstr, phsleModel);
3573:
3574: //- register number of math components
3575:
3576: pmca->iMathComponents = mcd.iCurrentType;
3577:
3578: //- do a consistency check on the types encountered during the two traversals
3579:
3580: if (mcd.piTypes[mcd.iCurrentType] != -1)
3581: {
3582: MathComponentDataStatusSet(&mcd, STATUS_CONSISTENCY, ptstr->ppist);
3583:
3584: iResult = FALSE;
3585: }
3586: }
3587: else
3588: {
3589: MathComponentDataStatusSet(&mcd, STATUS_MEMORY, ptstr->ppist);
3590:
3591: iResult = FALSE;
3592: }
3593: }
3594: else
3595: {
3596: MathComponentDataStatusSet(&mcd, STATUS_MEMORY, ptstr->ppist);
3597:
3598: iResult = FALSE;
3599: }
3600: }
3601: else
3602: {
3603: MathComponentDataStatusSet(&mcd, STATUS_MEMORY, ptstr->ppist);
3604:
3605: iResult = FALSE;
3606: }
3607: }
3608: }
3609:
3610: //t sort the registry
3611:
3612: //- link the mathcomponents together
3613:
3614: iResult = iResult && cellsolver_linkmathcomponents(pheccer, &mcd);
3615:
3616: //- delete treespace traversal
3617:
3618: TstrDelete(ptstr);
3619:
3620: //t decide if we want to keep piTypes or not, it might
3621: //t be useful to keep.
3622:
3623: //- delete channel contributors registry
3624:
3625: {
3626: int i;
3627:
3628: for (i = 0 ; i < MAXIMUM_NUMBER_OF_CHANNEL_CONTRIBUTORS ; i++)
3629: {
3630: free(mcd.ppiConnectors[i]);
3631: }
3632:
3633: free(mcd.ppiConnectors);
3634: }
3635:
3636: if (mcd.iStatus < 0)
3637: {
3638: HeccerError
3639: (pheccer,
3640: NULL,
3641: "extracting the model from the model-container at %s "
3642: "[cellsolver_getmathcomponents() returned error code (%i, %s),"
3643: " last processed mathcomponent is %i,"
3644: " external error return is %i.]",
3645: mcd.pcContext,
3646: mcd.iStatus,
3647: ppcStatusMessages[- mcd.iStatus],
3648: mcd.iCurrentType,
3649: iResult);
3650: }
3651: }
3652: else
3653: {
3654: iResult = FALSE;
3655: }
3656:
3657: //- return result
3658:
3659: return(iResult);
3660: }
3661:
3662:
3663: static int cellsolver_linkmathcomponents(struct Heccer * pheccer, struct MathComponentData * pmcd)
3664: {
3665: //- set default result : ok
3666:
3667: int iResult = TRUE;
3668:
3669: //- if there are no math components
3670:
3671: struct Intermediary *pinter = &pheccer->inter;
3672:
3673: struct MathComponentArray * pmca = pinter->pmca;
3674:
3675: if (!pmca)
3676: {
3677: //- linking is trivial
3678:
3679: return(TRUE);
3680: }
3681:
3682: //- loop over all mathcomponents
3683:
3684: struct MathComponent * pmc = pmca->pmc;
3685:
3686: int iMathComponent;
3687:
3688: for (iMathComponent = 0 ; iMathComponent < pmca->iMathComponents ; iMathComponent++)
3689: {
3690: //- get type of math component
3691:
3692: int iType = pmc->iType;
3693:
3694: switch (iType)
3695: {
3696: case MATH_TYPE_ChannelAct:
3697: {
3698: struct ChannelAct * pca = (struct ChannelAct *)pmc;
3699:
3700: //- if channel in contributors registry
3701:
3702: pca->iPool = ConnectionSource2Target(pmcd, pmc);
3703:
3704: int iPoolSerial = pca->iPool;
3705:
3706: if (iPoolSerial != -1)
3707: {
3708: //- translate the contributee serial
3709:
3710: int iPoolIndex = MathComponentArrayLookupSerial(pmca, iPoolSerial);
3711:
3712: pca->iPool = iPoolIndex;
3713: }
3714:
3715: //- if solved reversal potential
3716:
3717: if (pca->iReversalPotential != -1)
3718: {
3719: //- translate the serial to an index
3720:
3721: int iReversalPotential = MathComponentArrayLookupSerial(pmca, pca->iReversalPotential);
3722:
3723: pca->iReversalPotential = iReversalPotential;
3724: }
3725:
3726: break;
3727: }
3728: case MATH_TYPE_ChannelActInact:
3729: {
3730: struct ChannelActInact * pcai = (struct ChannelActInact *)pmc;
3731:
3732: //- if channel in contributors registry
3733:
3734: pcai->iPool = ConnectionSource2Target(pmcd, pmc);
3735:
3736: int iPoolSerial = pcai->iPool;
3737:
3738: if (iPoolSerial != -1)
3739: {
3740: //- translate the contributee serial
3741:
3742: int iPoolIndex = MathComponentArrayLookupSerial(pmca, iPoolSerial);
3743:
3744: pcai->iPool = iPoolIndex;
3745: }
3746:
3747: //- if solved reversal potential
3748:
3749: if (pcai->iReversalPotential != -1)
3750: {
3751: //- translate the serial to an index
3752:
3753: int iReversalPotential = MathComponentArrayLookupSerial(pmca, pcai->iReversalPotential);
3754:
3755: pcai->iReversalPotential = iReversalPotential;
3756: }
3757:
3758: break;
3759: }
3760: case MATH_TYPE_ChannelPersistentSteadyStateDualTau:
3761: {
3762: struct ChannelPersistentSteadyStateDualTau * pcpsdt = (struct ChannelPersistentSteadyStateDualTau *)pmc;
3763:
3764: //- if channel in contributors registry
3765:
3766: pcpsdt->iPool = ConnectionSource2Target(pmcd, pmc);
3767:
3768: int iPoolSerial = pcpsdt->iPool;
3769:
3770: if (iPoolSerial != -1)
3771: {
3772: //- translate the contributee serial
3773:
3774: int iPoolIndex = MathComponentArrayLookupSerial(pmca, iPoolSerial);
3775:
3776: pcpsdt->iPool = iPoolIndex;
3777: }
3778:
3779: //- if solved reversal potential
3780:
3781: if (pcpsdt->iReversalPotential != -1)
3782: {
3783: //- translate the serial to an index
3784:
3785: int iReversalPotential = MathComponentArrayLookupSerial(pmca, pcpsdt->iReversalPotential);
3786:
3787: pcpsdt->iReversalPotential = iReversalPotential;
3788: }
3789:
3790: break;
3791: }
3792: case MATH_TYPE_ChannelPersistentSteadyStateTau:
3793: {
3794: struct ChannelPersistentSteadyStateTau * pcpst = (struct ChannelPersistentSteadyStateTau *)pmc;
3795:
3796: //- if channel in contributors registry
3797:
3798: pcpst->iPool = ConnectionSource2Target(pmcd, pmc);
3799:
3800: int iPoolSerial = pcpst->iPool;
3801:
3802: if (iPoolSerial != -1)
3803: {
3804: //- translate the contributee serial
3805:
3806: int iPoolIndex = MathComponentArrayLookupSerial(pmca, iPoolSerial);
3807:
3808: pcpst->iPool = iPoolIndex;
3809: }
3810:
3811: //- if solved reversal potential
3812:
3813: if (pcpst->iReversalPotential != -1)
3814: {
3815: //- translate the serial to an index
3816:
3817: int iReversalPotential = MathComponentArrayLookupSerial(pmca, pcpst->iReversalPotential);
3818:
3819: pcpst->iReversalPotential = iReversalPotential;
3820: }
3821:
3822: break;
3823: }
3824: case MATH_TYPE_ChannelSteadyStateSteppedTau:
3825: {
3826: struct ChannelSteadyStateSteppedTau * pcsst = (struct ChannelSteadyStateSteppedTau *)pmc;
3827:
3828: //- if channel in contributors registry
3829:
3830: pcsst->iPool = ConnectionSource2Target(pmcd, pmc);
3831:
3832: int iPoolSerial = pcsst->iPool;
3833:
3834: if (iPoolSerial != -1)
3835: {
3836: //- translate the contributee serial
3837:
3838: int iPoolIndex = MathComponentArrayLookupSerial(pmca, iPoolSerial);
3839:
3840: pcsst->iPool = iPoolIndex;
3841: }
3842:
3843: //- if solved reversal potential
3844:
3845: if (pcsst->iReversalPotential != -1)
3846: {
3847: //- translate the serial to an index
3848:
3849: int iReversalPotential = MathComponentArrayLookupSerial(pmca, pcsst->iReversalPotential);
3850:
3851: pcsst->iReversalPotential = iReversalPotential;
3852: }
3853:
3854: break;
3855: }
3856: case MATH_TYPE_ChannelSpringMass:
3857: {
3858: struct ChannelSpringMass * pcsm = (struct ChannelSpringMass *)pmc;
3859:
3860: //- if channel in contributors registry
3861:
3862: pcsm->iPool = ConnectionSource2Target(pmcd, pmc);
3863:
3864: int iPoolSerial = pcsm->iPool;
3865:
3866: if (iPoolSerial != -1)
3867: {
3868: //- translate the contributee serial
3869:
3870: int iPoolIndex = MathComponentArrayLookupSerial(pmca, iPoolSerial);
3871:
3872: pcsm->iPool = iPoolIndex;
3873: }
3874:
3875: //- if solved reversal potential
3876:
3877: if (pcsm->iReversalPotential != -1)
3878: {
3879: //- translate the serial to an index
3880:
3881: int iReversalPotential = MathComponentArrayLookupSerial(pmca, pcsm->iReversalPotential);
3882:
3883: pcsm->iReversalPotential = iReversalPotential;
3884: }
3885:
3886: break;
3887: }
3888: case MATH_TYPE_ChannelActConc:
3889: {
3890: struct ChannelActConc * pcac = (struct ChannelActConc *)pmc;
3891:
3892: //- if channel in contributors registry
3893:
3894: pcac->iPool = ConnectionSource2Target(pmcd, pmc);
3895:
3896: int iPoolSerial = pcac->iPool;
3897:
3898: if (iPoolSerial != -1)
3899: {
3900: int iPoolIndex = MathComponentArrayLookupSerial(pmca, iPoolSerial);
3901:
3902: pcac->iPool = iPoolIndex;
3903: }
3904:
3905: //- translate iActivator
3906:
3907: if (pcac->pac.ca.iActivator != -1)
3908: {
3909: int iActivator = MathComponentArrayLookupSerial(pmca, pcac->pac.ca.iActivator);
3910:
3911: pcac->pac.ca.iActivator = iActivator;
3912: }
3913:
3914: /* //- or */
3915:
3916: /* else */
3917: /* { */
3918: /* //- an error */
3919:
3920: /* MathComponentDataStatusSet(pmcd, STATUS_CONSISTENCY); , ptstr->ppist */
3921:
3922: /* iResult = FALSE; */
3923: /* } */
3924:
3925: //- if solved reversal potential
3926:
3927: if (pcac->iReversalPotential != -1)
3928: {
3929: //- translate the serial to an index
3930:
3931: int iReversalPotential = MathComponentArrayLookupSerial(pmca, pcac->iReversalPotential);
3932:
3933: pcac->iReversalPotential = iReversalPotential;
3934: }
3935:
3936: break;
3937: }
3938: case MATH_TYPE_InternalNernst:
3939: {
3940: struct InternalNernst * pin = (struct InternalNernst *)pmc;
3941:
3942: //- if solved internal concentration
3943:
3944: //! must not be -1
3945:
3946: if (pin->iInternal != -1)
3947: {
3948: //- translate the serial to an index
3949:
3950: int iInternal = MathComponentArrayLookupSerial(pmca, pin->iInternal);
3951:
3952: pin->iInternal = iInternal;
3953: }
3954:
3955: break;
3956: }
3957: case MATH_TYPE_ExponentialDecay:
3958: {
3959: struct ExponentialDecay * pexdec = (struct ExponentialDecay *)pmc;
3960:
3961: int i;
3962:
3963: for (i = 0 ; i < EXPONENTIALDECAY_CONTRIBUTORS ; i++)
3964: {
3965: int iExternalSerial = pexdec->piExternal[i];
3966:
3967: if (iExternalSerial != -1)
3968: {
3969: int iExternalIndex = MathComponentArrayLookupSerial(pmca, iExternalSerial);
3970:
3971: pexdec->piExternal[i] = iExternalIndex;
3972: }
3973: }
3974: break;
3975: }
3976: case MATH_TYPE_SpikeGenerator:
3977: {
3978: struct SpikeGenerator * psg = (struct SpikeGenerator *)pmc;
3979:
3980: //- ok
3981:
3982: break;
3983: }
3984: default:
3985: {
3986: iResult = FALSE;
3987:
3988: break;
3989: }
3990: }
3991:
3992: if (iResult)
3993: {
3994: //- advance to the next math component
3995:
3996: pmc = MathComponentNext(pmc);
3997: }
3998: }
3999:
4000: //- return result
4001:
4002: return(iResult);
4003: }
4004:
4005:
4006: int HeccerNeurospacesMechanisms2MathComponents(struct TranslationService *pts)
4007: {
4008: //- set the service function pointer to cellsolver_getmathcomponents()
4009:
4010: pts->mechanisms_inspector = cellsolver_getmathcomponents;
4011:
4012: //- return result
4013:
4014: return(1);
4015: }
4016:
4017:
4018: static
4019: TreespaceTraversalProcessor *
4020: Type2Processor(int iType)
4021: {
4022: //- set default result : none
4023:
4024: TreespaceTraversalProcessor *pfResult = NULL;
4025:
4026: if (iType == MATH_TYPE_ChannelActInact)
4027: {
4028: pfResult = solver_channel_activation_inactivation_processor;
4029: }
4030: else if (iType == MATH_TYPE_ChannelActConc)
4031: {
4032: pfResult = solver_channel_activation_concentration_processor;
4033: }
4034: else if (iType == MATH_TYPE_ChannelSteadyStateSteppedTau)
4035: {
4036: pfResult = solver_channel_steadystate_steppedtau_processor;
4037: }
4038: else if (iType == MATH_TYPE_ChannelPersistentSteadyStateTau)
4039: {
4040: pfResult = solver_channel_persistent_steadystate_tau_processor;
4041: }
4042: else if (iType == MATH_TYPE_ChannelPersistentSteadyStateDualTau)
4043: {
4044: pfResult = solver_channel_persistent_steadystate_dualtau_processor;
4045: }
4046: else if (iType == MATH_TYPE_ChannelAct)
4047: {
4048: pfResult = solver_channel_activation_processor;
4049: }
4050: else if (iType == MATH_TYPE_ChannelSpringMass)
4051: {
4052: pfResult = solver_channel_springmass_processor;
4053: }
4054: else
4055: {
4056: //t segv
4057:
4058: ((int *)0)[0] = 0;
4059: }
4060:
4061: //- return result
4062:
4063: return(pfResult);
4064: }
4065:
4066:
4067:
Generated by Xrefactory version 2.0.14 on Thu Jul 24 22:41:20 2008