file:/local_home/local_home/hugo/neurospaces_project/heccer/source/c/snapshots/0/addressing.c (Thu Jul 3 16:50:45 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 <limits.h>
20: #include <stdio.h>
21: #include <stdlib.h>
22: #include <string.h>
23: #include <strings.h>
24:
25: #include "heccer/addressing.h"
26: #include "heccer/heccer.h"
27: #include "heccer/mathcomponent.h"
28:
29:
30: #ifdef HECCER_SOURCE_NEUROSPACES
31:
32: static
33: int
34: HeccerAddressCompartmentSerial2Intermediary
35: (struct Heccer *pheccer, int iSerial, char *pcType);
36: #endif
37:
38: #ifdef HECCER_SOURCE_NEUROSPACES
39: static
40: int
41: HeccerAddressSerial2Intermediary
42: (struct Heccer *pheccer, int iIndex, char *pcType);
43:
44: #endif
45:
46:
47: /// **************************************************************************
48: ///
49: /// SHORT: HeccerAddressableSet()
50: ///
51: /// ARGS.:
52: ///
53: /// pheccer...: a heccer.
54: /// iSerial...: identification number.
55: /// pcType....: name of requested variable.
56: /// dValue....: new value for this variable.
57: ///
58: /// RTN..: char *
59: ///
60: /// error code, NULL for success.
61: ///
62: /// DESCR: Set a variable in a compiled model.
63: ///
64: /// **************************************************************************
65:
66: #ifdef HECCER_SOURCE_NEUROSPACES
67: char *
68: HeccerAddressableSet
69: (struct Heccer *pheccer, int iSerial, char *pcType, double dValue)
70: {
71: //- set default result: success
72:
73: char *pcResult = NULL;
74:
75: //- find the addressable
76:
77: double *pd = HeccerAddressVariable(pheccer, iSerial, pcType);
78:
79: if (pd)
80: {
81: //- set the value
82:
83: *pd = dValue;
84: }
85: else
86: {
87: pcResult = "Variable cannot be found in this compiled heccer instance";
88: }
89:
90: //- return result
91:
92: return(pcResult);
93: }
94: #endif
95:
96:
97: /// **************************************************************************
98: ///
99: /// SHORT: HeccerAddressAggregator()
100: ///
101: /// ARGS.:
102: ///
103: /// pheccer...: a heccer.
104: /// iSerial...: identification number.
105: /// pcType....: name of requested variable.
106: ///
107: /// RTN..: void *
108: ///
109: /// address of the aggregator, NULL for failure.
110: ///
111: /// DESCR: Get the address of an aggregator.
112: ///
113: /// **************************************************************************
114:
115: void *
116: HeccerAddressAggregator
117: (struct Heccer *pheccer, int iSerial, char *pcType)
118: {
119: //- set default result: not found
120:
121: char *pvResult = NULL;
122:
123: //- process as an aggregator variable
124:
125: if (strncasecmp(pcType, "aggregator", strlen("aggregator")) == 0)
126: {
127: //- find the requested index
128:
129: int iIndex = -1;
130:
131: int iAssigned = sscanf(pcType, "aggregator[%i]", &iIndex);
132:
133: if (iAssigned == 1)
134: {
135: if (iIndex < pheccer->vm.iAggregators)
136: {
137: //- set result
138:
139: pvResult = (void *)&pheccer->vm.pdAggregators[iIndex];
140: }
141: else
142: {
143: HeccerError
144: (pheccer,
145: "HeccerAddressAggregator()",
146: "aggregator index of %s is out of range (internal serial %i)",
147: pcType,
148: iSerial);
149: }
150: }
151: else
152: {
153: HeccerError
154: (pheccer,
155: "HeccerAddressAggregator()",
156: "invalid aggregator %s (internal serial %i)",
157: pcType,
158: iSerial);
159: }
160: }
161:
162: //- return resulting address if variable was found
163:
164: return(pvResult);
165: }
166:
167:
168: /// **************************************************************************
169: ///
170: /// SHORT: HeccerAddressCompartmentVariable()
171: ///
172: /// ARGS.:
173: ///
174: /// pheccer.......: a heccer.
175: /// iIntermediary.: index of compartment in the intermediary.
176: /// pcType........: name of requested variable.
177: ///
178: /// RTN..: void *
179: ///
180: /// pointer to the requested field, NULL for failure.
181: ///
182: /// DESCR: Find the simulation sequence of a given variable.
183: ///
184: /// **************************************************************************
185:
186: void *
187: HeccerAddressCompartmentVariable
188: (struct Heccer *pheccer, int iIntermediary, char *pcType)
189: {
190: //- set default result : not found
191:
192: void *pvResult = NULL;
193:
194: //- for membrane potential
195:
196: if (strcasecmp(pcType, "Vm") == 0)
197: {
198: //- convert intermediary to schedule number
199:
200: int iSchedule = pheccer->indexers.md.piForward[iIntermediary];
201:
202: //- set result
203:
204: double *pdResult = &pheccer->vm.pdVms[iSchedule];
205:
206: pvResult = (void *)pdResult;
207: }
208:
209: //- for injected current
210:
211: else if (strcasecmp(pcType, "inject") == 0)
212: {
213: //- convert intermediary to schedule number
214:
215: int iSchedule = pheccer->indexers.md.piForward[iIntermediary];
216:
217: //- get entry in mat array
218:
219: struct MatsCompartment *pmatsc
220: = (struct MatsCompartment *)pheccer->vm.ppvCMatsIndex[iSchedule];
221:
222: //- set result
223:
224: double *pdResult = &pmatsc->dInjected;
225:
226: pvResult = (void *)pdResult;
227: }
228:
229: //- for total membrane current
230:
231: else if (strcasecmp(pcType, "Im") == 0)
232: {
233: }
234:
235: //- for membrane leak current
236:
237: else if (strcasecmp(pcType, "Ileak") == 0)
238: {
239: }
240:
241: //- return result
242:
243: return(pvResult);
244: }
245:
246:
247: /// **************************************************************************
248: ///
249: /// SHORT: HeccerAddressCompartmentSerial2Intermediary()
250: ///
251: /// ARGS.:
252: ///
253: /// pheccer...: a heccer.
254: /// iSerial...: identification number.
255: /// pcType....: name of requested variable.
256: ///
257: /// RTN..: int
258: ///
259: /// index into the intermediary, -1 for not found.
260: ///
261: /// DESCR: Lookup the index of the given serial.
262: ///
263: /// **************************************************************************
264:
265: #ifdef HECCER_SOURCE_NEUROSPACES
266: static
267: int
268: HeccerAddressCompartmentSerial2Intermediary
269: (struct Heccer *pheccer, int iSerial, char *pcType)
270: {
271: //- set default result : not found
272:
273: int iResult = -1;
274:
275: //- loop over the compartment intermediary
276:
277: int i;
278:
279: for (i = 0; i < pheccer->inter.iCompartments ; i++)
280: {
281: //- get current compartment
282:
283: struct Compartment *pcomp = &pheccer->inter.pcomp[i];
284:
285: //- if serial matches
286:
287: if (pcomp->mc.iSerial == iSerial)
288: {
289: //t check if the field type is 'compatible' with the math component
290:
291: //- set result : current index
292:
293: iResult = i;
294:
295: //- break searching loop
296:
297: break;
298: }
299: }
300:
301: //- return result
302:
303: return(iResult);
304: }
305: #endif
306:
307:
308: /// **************************************************************************
309: ///
310: /// SHORT: HeccerAddressMechanismSerial2Intermediary()
311: ///
312: /// ARGS.:
313: ///
314: /// pheccer...: a heccer.
315: /// iSerial...: identification number.
316: /// pcType....: name of requested variable.
317: ///
318: /// RTN..: int
319: ///
320: /// index into the intermediary, -1 for not found.
321: ///
322: /// DESCR: Lookup the index of the given serial.
323: ///
324: /// **************************************************************************
325:
326: #ifdef HECCER_SOURCE_NEUROSPACES
327: static
328: int
329: HeccerAddressMechanismSerial2Intermediary
330: (struct Heccer *pheccer, int iSerial, char *pcType)
331: {
332:
333: //- set default result : not found
334:
335: int iResult = -1;
336:
337: //- loop over the math components intermediary
338:
339: struct MathComponent *pmc = pheccer->inter.pmca->pmc;
340:
341: int i;
342:
343: for (i = 0; i < pheccer->inter.pmca->iMathComponents ; i++)
344: {
345: //- if searched serial lower than current serial
346:
347: if (pmc->iSerial > iSerial)
348: {
349: //- break searching loop
350:
351: break;
352: }
353:
354: //- go to next math component
355:
356: pmc = MathComponentNext(pmc);
357: }
358:
359: //- set result : previous index
360:
361: iResult = i - 1;
362:
363: //- return result
364:
365: return(iResult);
366: }
367: #endif
368:
369:
370: /// **************************************************************************
371: ///
372: /// SHORT: HeccerAddressMechanismVariable()
373: ///
374: /// ARGS.:
375: ///
376: /// pheccer.......: a heccer.
377: /// iIntermediary.: index of mechanism in the intermediary.
378: /// pcType........: name of requested variable.
379: ///
380: /// RTN..: void *
381: ///
382: /// pointer to the requested field, NULL for failure.
383: ///
384: /// DESCR: Find the simulation sequence of a given variable.
385: ///
386: /// **************************************************************************
387:
388: void *
389: HeccerAddressMechanismVariable
390: (struct Heccer *pheccer, int iIndex, char *pcType)
391: {
392: //- set default result : not found
393:
394: void *pvResult = NULL;
395:
396: //- lookup the field operand, we first search for mat entries
397:
398: //! negative offset for now
399:
400: struct field_2_operator
401: {
402: char *pcType;
403: int iOperand;
404: int iOffset;
405: };
406:
407: struct field_2_operator pF2P[] =
408: {
409: { "Ca", 0, 0, },
410: { "spike", 0, 1, },
411: { "state_h", 0, 0, },
412: { "state_m", -1, 0, },
413: { "state_n", 0, 0, },
414: { NULL, INT_MAX, INT_MAX, },
415: };
416:
417: int iField;
418:
419: for (iField = 0 ; pF2P[iField].pcType ; iField++)
420: {
421: if (strcasecmp(pcType, pF2P[iField].pcType) == 0)
422: {
423: break;
424: }
425: }
426:
427: //- if mat entry found
428:
429: int iOperand = pF2P[iField].iOperand;
430:
431: if (iOperand != INT_MAX)
432: {
433: //- get mat number
434:
435: int iMat = pheccer->vm.piMC2Mat[iIndex].iMat;
436:
437: //- apply the operand
438:
439: iMat += iOperand;
440:
441: //- set result
442:
443: int iOffset = (double *)pheccer->vm.ppvMatsIndex[iMat] - (double *)pheccer->vm.pvMats;
444:
445: printf("mat number for intermediary mechanism %i is mat %i, starts at %i, offset is %i\n", iIndex, iMat, iOffset, pF2P[iField].iOffset);
446:
447: //! note that this is implicitly assumed to be a pointer to double.
448:
449: pvResult = &((double *)pheccer->vm.ppvMatsIndex[iMat])[pF2P[iField].iOffset];
450: }
451:
452: //- else
453:
454: else
455: {
456: //- we try mop entries
457:
458: if (strcasecmp(pcType, "table_A_index") == 0)
459: {
460: //- operators are two off
461:
462: iOperand = -2;
463: }
464: else if (strcasecmp(pcType, "table_B_index") == 0)
465: {
466: //- operators are one off
467:
468: iOperand = -1;
469: }
470:
471: if (iOperand != INT_MAX)
472: {
473: //- get mop number
474:
475: int iMop = pheccer->vm.piMC2Mop[iIndex];
476:
477: //- apply the operand
478:
479: iMop += iOperand;
480:
481: //- set result
482:
483: int iOffset = (int *)pheccer->vm.ppvMopsIndex[iMop] - (int *)pheccer->vm.pvMops;
484:
485: printf("mop number for intermediary mechanism %i is mop %i, starts at %i, offset is %i\n", iIndex, iMop, iOffset, 0);
486:
487: struct MopsSingleGateConcept *pmops = (struct MopsSingleGateConcept *)((int *)pheccer->vm.ppvMopsIndex[iMop]);
488:
489: printf("table index is %i\n", pmops->iTableIndex);
490:
491: //! normally the default for iTableIndex is -1, which is
492: //! returned as an error indicator if there is no table
493: //! associated with this gate.
494:
495: pvResult = (int *)pmops->iTableIndex;
496: }
497: }
498:
499: //- return result
500:
501: return(pvResult);
502: }
503:
504:
505: /// **************************************************************************
506: ///
507: /// SHORT: HeccerAddressSerial2Intermediary()
508: ///
509: /// ARGS.:
510: ///
511: /// pheccer...: a heccer.
512: /// iSerial...: identification number.
513: /// pcType....: name of requested variable.
514: ///
515: /// RTN..: int
516: ///
517: /// index into the intermediary, -1 for not found.
518: ///
519: /// DESCR: Lookup the index of the given serial.
520: ///
521: /// Note that depending on the field, you get an index into
522: /// mechanisms or an index into the compartments.
523: ///
524: /// **************************************************************************
525:
526: #ifdef HECCER_SOURCE_NEUROSPACES
527: static
528: int
529: HeccerAddressSerial2Intermediary
530: (struct Heccer *pheccer, int iSerial, char *pcType)
531: {
532: //- set default result: not found
533:
534: int iResult = -1;
535:
536: //- for compartment addressables
537:
538: /* if (strcmp(pcType, "Vm") == 0 */
539: /* || strcmp(pcType, "inject") == 0 */
540: /* || strcmp(pcType, "Im") == 0 */
541: /* || strcmp(pcType, "Ileak") == 0) */
542: if (strcasecmp(pcType, "Vm") == 0
543: || strcasecmp(pcType, "inject") == 0
544: || strcasecmp(pcType, "Im") == 0
545: || strcasecmp(pcType, "Ileak") == 0)
546: {
547: iResult = HeccerAddressCompartmentSerial2Intermediary(pheccer, iSerial, pcType);
548: }
549: else
550: {
551: iResult = HeccerAddressMechanismSerial2Intermediary(pheccer, iSerial, pcType);
552: }
553:
554: //- return result
555:
556: return(iResult);
557: }
558: #endif
559:
560:
561: /// **************************************************************************
562: ///
563: /// SHORT: HeccerAddressTableIndex()
564: ///
565: /// ARGS.:
566: ///
567: /// pheccer...: a heccer.
568: /// iSerial...: identification number.
569: /// pcType....: name of requested variable.
570: ///
571: /// RTN..: int
572: ///
573: /// index into table array, -1 for failure.
574: ///
575: /// DESCR: Lookup the table index of the given serial.
576: ///
577: /// The returned index is an address into ptgt->phtg. See table.h
578: /// for more information.
579: ///
580: /// **************************************************************************
581:
582: int
583: HeccerAddressTableIndex
584: (struct Heccer *pheccer, int iSerial, char *pcType)
585: {
586: //- set default result : not found
587:
588: int iResult = -1;
589:
590: //- do a regular lookup
591:
592: void *pvResult = HeccerAddressVariable(pheccer, iSerial, pcType);
593:
594: //t should be cleaner than this
595:
596: //- convert result to int
597:
598: iResult = (int)pvResult;
599:
600: //- return result
601:
602: return(iResult);
603: }
604:
605:
606: /// **************************************************************************
607: ///
608: /// SHORT: HeccerAddressVariable()
609: ///
610: /// ARGS.:
611: ///
612: /// pheccer...: a heccer.
613: /// iSerial...: identification number.
614: /// pcType....: name of requested variable.
615: ///
616: /// RTN..: void *
617: ///
618: /// pointer to the requested field, NULL for failure.
619: ///
620: /// DESCR: Find the simulation sequence of a given variable.
621: ///
622: /// In all cases, as of the moment of writing, the pointer is a
623: /// pointer to a double.
624: ///
625: /// **************************************************************************
626:
627: void *
628: HeccerAddressVariable
629: (struct Heccer *pheccer, int iSerial, char *pcType)
630: #ifdef HECCER_SOURCE_NEUROSPACES
631: {
632: //- set default result : not found
633:
634: void *pvResult = NULL;
635:
636: iSerial = ADDRESSING_NEUROSPACES_2_HECCER(iSerial);
637:
638: //- if this is the serial of the model itself
639:
640: if (iSerial == pheccer->inter.iSerialStart)
641: {
642: //- address as an aggregator
643:
644: pvResult = HeccerAddressAggregator(pheccer, iSerial, pcType);
645:
646: return(pvResult);
647: }
648:
649: //- if serial not within range
650:
651: if (iSerial < pheccer->inter.iSerialStart
652: || iSerial > pheccer->inter.iSerialEnd)
653: {
654: //- return failure
655:
656: return(NULL);
657: }
658:
659: //- convert the serial to an intermediary index
660:
661: int iIntermediary = HeccerAddressSerial2Intermediary(pheccer, iSerial, pcType);
662:
663: if (iIntermediary != -1)
664: {
665: //- for compartment addressables
666:
667: /* if (strcmp(pcType, "Vm") == 0 */
668: /* || strcmp(pcType, "inject") == 0 */
669: /* || strcmp(pcType, "Im") == 0 */
670: /* || strcmp(pcType, "Ileak") == 0) */
671: if (strcasecmp(pcType, "Vm") == 0
672: || strcasecmp(pcType, "inject") == 0
673: || strcasecmp(pcType, "Im") == 0
674: || strcasecmp(pcType, "Ileak") == 0)
675: {
676: pvResult = HeccerAddressCompartmentVariable(pheccer, iIntermediary, pcType);
677: }
678: else
679: {
680: pvResult = HeccerAddressMechanismVariable(pheccer, iIntermediary, pcType);
681: }
682: }
683: else
684: {
685: //! this cannot be, internal error
686:
687: HeccerError
688: (pheccer,
689: "HeccerAddressVariable()",
690: "trying to address something that should exist, but cannot find it (internal serial %i)",
691: iSerial);
692:
693: //- return error
694:
695: return(NULL);
696: }
697:
698: //- return result
699:
700: return(pvResult);
701: }
702: #else
703: {
704: return(NULL);
705: }
706: #endif
707:
708:
709:
Generated by Xrefactory version 2.0.14 on Thu Jul 24 22:41:20 2008