001: // 002: // Heccer : a compartmental solver that implements efficient Crank-Nicolson 003: // integration for neuronal models. 004: // 005: 006: ////////////////////////////////////////////////////////////////////////////// 007: //' 008: //' Heccer : testbed C implementation 009: //' 010: //' Copyright (C) 2006-2008 Hugo Cornelis 011: //' 012: //' functional ideas .. Hugo Cornelis, hugo.cornelis@gmail.com 013: //' 014: //' coding ............ Hugo Cornelis, hugo.cornelis@gmail.com 015: //' 016: ////////////////////////////////////////////////////////////////////////////// 017: 018: 019: #include <stdlib.h> 020: 021: #include "../../heccer/addressing.h" 022: #include "../../heccer/compartment.h" 023: #include "../../heccer/heccer.h" 024: 025: 026: #define HECCER_TEST_OPTIONS (HECCER_OPTION_ENABLE_AGGREGATORS | HECCER_OPTION_ENABLE_INDIVIDUAL_CURRENTS) 027: #define HECCER_TEST_TESTED_THINGS ( HECCER_DUMP_VM_COMPARTMENT_MATRIX \ 028: | HECCER_DUMP_VM_COMPARTMENT_MATRIX_DIAGONALS \ 029: | HECCER_DUMP_VM_COMPARTMENT_OPERATIONS \ 030: | HECCER_DUMP_VM_MECHANISM_DATA \ 031: | HECCER_DUMP_VM_MECHANISM_OPERATIONS \ 032: | HECCER_DUMP_VM_SUMMARY \ 033: | HECCER_DUMP_VM_AGGREGATORS \ 034: ) 035: #define HECCER_TEST_TIME_STEP (6e-6) 036: 037: 038: struct Compartment pcomp[] = 039: { 040: { 041: //m administrative overhead 042: 043: { 044: //m type of structure 045: 046: MATH_TYPE_Compartment, 047: 048: #ifdef HECCER_SOURCE_NEUROSPACES 049: 050: //m identification 051: 052: ADDRESSING_NEUROSPACES_2_HECCER(1000), 053: 054: #endif 055: 056: #ifdef HECCER_SOURCE_TYPING 057: 058: //m model source type number 059: 060: //! source typing is used to compute aggregate currents ao 061: //! things. 062: 063: -1, 064: 065: #endif 066: 067: }, 068: 069: //m index of parent compartment, -1 for none 070: 071: -1, 072: 073: /* //m first mechanism */ 074: 075: /* NULL, */ 076: 077: /* //m number of mechanisms */ 078: 079: /* 0, */ 080: 081: //m descriptive values, alphabetical order 082: 083: /* double dCm; */ 084: 085: 4.57537e-11, // unscaled 0.0164, 086: 087: /* double dEm; */ 088: 089: -0.08, 090: 091: /* double dInitVm; */ 092: 093: -0.028, 094: 095: /* double dInject; */ 096: 097: 0, 098: 099: /* double dRa; */ 100: 101: 360502, // unscaled 2.5, 102: 103: /* double dRm; */ 104: 105: 3.58441e+08, // unscaled 1 106: }, 107: 108: { 109: //m administrative overhead 110: 111: { 112: //m type of structure 113: 114: MATH_TYPE_Compartment, 115: 116: #ifdef HECCER_SOURCE_NEUROSPACES 117: 118: //m identification 119: 120: ADDRESSING_NEUROSPACES_2_HECCER(2000), 121: 122: #endif 123: 124: #ifdef HECCER_SOURCE_TYPING 125: 126: //m model source type number 127: 128: //! source typing is used to compute aggregate currents ao 129: //! things. 130: 131: -1, 132: 133: #endif 134: 135: }, 136: 137: //m index of parent compartment, -1 for none 138: 139: 0, 140: 141: /* //m first mechanism */ 142: 143: /* NULL, */ 144: 145: /* //m number of mechanisms */ 146: 147: /* 0, */ 148: 149: //m descriptive values, alphabetical order 150: 151: /* double dCm; */ 152: 153: 5.755329373e-12, // unscaled 0.0164, 154: 155: /* double dEm; */ 156: 157: -0.08, 158: 159: /* double dInitVm; */ 160: 161: -0.068, 162: 163: /* double dInject; */ 164: 165: 0, 166: 167: /* double dRa; */ 168: 169: 772813.4375, // unscaled 2.5, 170: 171: /* double dRm; */ 172: 173: 8.548598272e9, // unscaled 3 174: }, 175: }; 176: 177: 178: //v a simple fast sodium channel 179: 180: struct ChannelActInact pcaiCaT[] = 181: { 182: { 183: //m administrative overhead 184: 185: { 186: //m type of structure 187: 188: MATH_TYPE_ChannelActInact, 189: 190: #ifdef HECCER_SOURCE_NEUROSPACES 191: 192: //m identification 193: 194: ADDRESSING_NEUROSPACES_2_HECCER(3000), 195: 196: #endif 197: 198: #ifdef HECCER_SOURCE_TYPING 199: 200: //m model source type number 201: 202: //! source typing is used to compute aggregate currents ao 203: //! things. 204: 205: 0, 206: 207: #endif 208: 209: }, 210: 211: //m first set of descriptive values, alphabetical order 212: 213: //m initial reversal potential 214: 215: 0.1375262439, 216: 217: //m get reversal potential from this intermediary, -1 for none 218: 219: -1, 220: 221: //m maximal conductance when all channels are permissive 222: 223: 1.394928884e-08, 224: 225: //m contributes to this concentration pool, -1 for none, boolean indicator only. 226: 227: 1, 228: 229: //m activation description 230: 231: { 232: //m power, for a standard heccer, something between 1 and 4 or so. 233: 234: 1, 235: 236: //m gate definition 237: 238: { 239: //m initial value, commonly forward over backward steady states 240: 241: 0.038918706451336625, 242: 243: //m corresponding index in tables, set to -1 for initialization. 244: 245: -1, 246: 247: { 248: //m forward kinetiks, commonly denoted with alpha or non-perm to perm rate 249: 250: { 251: //m multiplier 252: 253: 2.6e3, 254: 255: //m multiplier membrane dependence, 0.0 for no dependence 256: 257: 0.0, 258: 259: //m 2b: multiplier membrane dependence offset, 0.0 for no dependence 260: 261: 0.0, 262: 263: //m choose between nominator or denominator, 1 means nominator, -1 264: //m means denominator 265: 266: -1.0, 267: 268: //m nominator or denominator offset 269: 270: 1.0, 271: 272: //m membrane offset 273: 274: 0.021, 275: 276: //m denormalized time constant 277: 278: -8e-3, 279: }, 280: 281: //m backward kinetiks, commonly denoted with beta or perm to non-perm rate 282: 283: { 284: //m multiplier 285: 286: 0.18e3, 287: 288: //m multiplier membrane dependence, 0.0 for no dependence 289: 290: 0.0, 291: 292: //m 2b: multiplier membrane dependence offset, 0.0 for no dependence 293: 294: 0.0, 295: 296: //m choose between nominator or denominator, 1 means nominator, -1 297: //m means denominator 298: 299: -1.0, 300: 301: //m nominator or denominator offset 302: 303: 1.0, 304: 305: //m membrane offset 306: 307: 0.04, 308: 309: //m denormalized time constant 310: 311: 4e-3, 312: }, 313: }, 314: }, 315: }, 316: 317: //m inactivation description 318: 319: { 320: //m power, for a standard heccer, something between 1 and 4 or so. 321: 322: 1, 323: 324: //m gate definition 325: 326: { 327: //m initial value, commonly forward over backward steady states 328: 329: 0.082602128127539254, 330: 331: //m corresponding index in tables, set to -1 for initialization. 332: 333: -1, 334: 335: { 336: //m forward kinetiks, commonly denoted with alpha or non-perm to perm rate 337: 338: { 339: //m multiplier 340: 341: 0.0025e3, 342: 343: //m multiplier membrane dependence, 0.0 for no dependence 344: 345: 0.0, 346: 347: //m 2b: multiplier membrane dependence offset, 0.0 for no dependence 348: 349: 0.0, 350: 351: //m choose between nominator or denominator, 1 means nominator, -1 352: //m means denominator 353: 354: -1.0, 355: 356: //m nominator or denominator offset 357: 358: 1.0, 359: 360: //m membrane offset 361: 362: 0.04, 363: 364: //m denormalized time constant 365: 366: 8e-3, 367: }, 368: 369: //m backward kinetiks, commonly denoted with beta or perm to non-perm rate 370: 371: { 372: //m multiplier 373: 374: 0.19e3, 375: 376: //m multiplier membrane dependence, 0.0 for no dependence 377: 378: 0.0, 379: 380: //m 2b: multiplier membrane dependence offset, 0.0 for no dependence 381: 382: 0.0, 383: 384: //m choose between nominator or denominator, 1 means nominator, -1 385: //m means denominator 386: 387: -1.0, 388: 389: //m nominator or denominator offset 390: 391: 1.0, 392: 393: //m membrane offset 394: 395: 0.05, 396: 397: //m denormalized time constant 398: 399: -10.0e-3, 400: }, 401: }, 402: }, 403: }, 404: }, 405: 406: { 407: //m administrative overhead 408: 409: { 410: //m type of structure 411: 412: MATH_TYPE_ChannelActInact, 413: 414: #ifdef HECCER_SOURCE_NEUROSPACES 415: 416: //m identification 417: 418: ADDRESSING_NEUROSPACES_2_HECCER(4000), 419: 420: #endif 421: 422: #ifdef HECCER_SOURCE_TYPING 423: 424: //m model source type number 425: 426: //! source typing is used to compute aggregate currents ao 427: //! things. 428: 429: 0, 430: 431: #endif 432: 433: }, 434: 435: //m first set of descriptive values, alphabetical order 436: 437: //m initial reversal potential 438: 439: 0.1470214874, 440: 441: //m get reversal potential from this intermediary, -1 for none 442: 443: -1, 444: 445: //m maximal conductance when all channels are permissive 446: 447: 1.754672296e-09, 448: 449: //m contributes to this concentration pool, -1 for none, boolean indicator only. 450: 451: 3, 452: 453: //m activation description 454: 455: { 456: //m power, for a standard heccer, something between 1 and 4 or so. 457: 458: 1, 459: 460: //m gate definition 461: 462: { 463: //m initial value, commonly forward over backward steady states 464: 465: 0.038918706451336625, 466: 467: //m corresponding index in tables, set to -1 for initialization. 468: 469: -1, 470: 471: { 472: //m forward kinetiks, commonly denoted with alpha or non-perm to perm rate 473: 474: { 475: //m multiplier 476: 477: 2.6e3, 478: 479: //m multiplier membrane dependence, 0.0 for no dependence 480: 481: 0.0, 482: 483: //m 2b: multiplier membrane dependence offset, 0.0 for no dependence 484: 485: 0.0, 486: 487: //m choose between nominator or denominator, 1 means nominator, -1 488: //m means denominator 489: 490: -1.0, 491: 492: //m nominator or denominator offset 493: 494: 1.0, 495: 496: //m membrane offset 497: 498: 0.021, 499: 500: //m denormalized time constant 501: 502: -8e-3, 503: }, 504: 505: //m backward kinetiks, commonly denoted with beta or perm to non-perm rate 506: 507: { 508: //m multiplier 509: 510: 0.18e3, 511: 512: //m multiplier membrane dependence, 0.0 for no dependence 513: 514: 0.0, 515: 516: //m 2b: multiplier membrane dependence offset, 0.0 for no dependence 517: 518: 0.0, 519: 520: //m choose between nominator or denominator, 1 means nominator, -1 521: //m means denominator 522: 523: -1.0, 524: 525: //m nominator or denominator offset 526: 527: 1.0, 528: 529: //m membrane offset 530: 531: 0.04, 532: 533: //m denormalized time constant 534: 535: 4e-3, 536: }, 537: }, 538: }, 539: }, 540: 541: //m inactivation description 542: 543: { 544: //m power, for a standard heccer, something between 1 and 4 or so. 545: 546: 1, 547: 548: //m gate definition 549: 550: { 551: //m initial value, commonly forward over backward steady states 552: 553: 0.082602128127539254, 554: 555: //m corresponding index in tables, set to -1 for initialization. 556: 557: -1, 558: 559: { 560: //m forward kinetiks, commonly denoted with alpha or non-perm to perm rate 561: 562: { 563: //m multiplier 564: 565: 0.0025e3, 566: 567: //m multiplier membrane dependence, 0.0 for no dependence 568: 569: 0.0, 570: 571: //m 2b: multiplier membrane dependence offset, 0.0 for no dependence 572: 573: 0.0, 574: 575: //m choose between nominator or denominator, 1 means nominator, -1 576: //m means denominator 577: 578: -1.0, 579: 580: //m nominator or denominator offset 581: 582: 1.0, 583: 584: //m membrane offset 585: 586: 0.04, 587: 588: //m denormalized time constant 589: 590: 8e-3, 591: }, 592: 593: //m backward kinetiks, commonly denoted with beta or perm to non-perm rate 594: 595: { 596: //m multiplier 597: 598: 0.19e3, 599: 600: //m multiplier membrane dependence, 0.0 for no dependence 601: 602: 0.0, 603: 604: //m 2b: multiplier membrane dependence offset, 0.0 for no dependence 605: 606: 0.0, 607: 608: //m choose between nominator or denominator, 1 means nominator, -1 609: //m means denominator 610: 611: -1.0, 612: 613: //m nominator or denominator offset 614: 615: 1.0, 616: 617: //m membrane offset 618: 619: 0.05, 620: 621: //m denormalized time constant 622: 623: -10.0e-3, 624: }, 625: }, 626: }, 627: }, 628: }, 629: }; 630: 631: 632: struct ExponentialDecay pexdecCa[] = 633: { 634: { 635: //m administrative overhead 636: 637: { 638: //m type of structure 639: 640: MATH_TYPE_ExponentialDecay, 641: 642: #ifdef HECCER_SOURCE_NEUROSPACES 643: 644: //m identification 645: 646: ADDRESSING_NEUROSPACES_2_HECCER(5000), 647: 648: #endif 649: 650: #ifdef HECCER_SOURCE_TYPING 651: 652: //m model source type number 653: 654: //! source typing is used to compute aggregate currents ao 655: //! things. 656: 657: 1, 658: 659: #endif 660: 661: }, 662: 663: //m initial value 664: 665: 4e-5, 666: 667: //m beta 668: 669: 7.579027046e+10, 670: 671: //m steady state 672: 673: 4e-05, 674: 675: //m tau 676: 677: 0.00010, 678: 679: //m external contribution delivered by these intermediaries 680: 681: { 682: 0, 683: -1, 684: -1, 685: -1, 686: }, 687: }, 688: 689: { 690: //m administrative overhead 691: 692: { 693: //m type of structure 694: 695: MATH_TYPE_ExponentialDecay, 696: 697: #ifdef HECCER_SOURCE_NEUROSPACES 698: 699: //m identification 700: 701: ADDRESSING_NEUROSPACES_2_HECCER(6000), 702: 703: #endif 704: 705: #ifdef HECCER_SOURCE_TYPING 706: 707: //m model source type number 708: 709: //! source typing is used to compute aggregate currents ao 710: //! things. 711: 712: 1, 713: 714: #endif 715: 716: }, 717: 718: //m initial value 719: 720: 4e-5, 721: 722: //m beta 723: 724: 9412391936.0, 725: 726: //m steady state 727: 728: 4e-05, 729: 730: //m tau 731: 732: 0.00020, 733: 734: //m external contribution delivered by these intermediaries 735: 736: { 737: 2, 738: -1, 739: -1, 740: -1, 741: }, 742: } 743: }; 744: 745: 746: int piC2m[] = 747: { 748: 2, 749: 4, 750: -1, 751: }; 752: 753: 754: struct MathComponentArray mca = 755: { 756: //m number of math components 757: 758: 4, 759: 760: //m math component data 761: 762: NULL, 763: 764: //m math component index, initialize to NULL 765: 766: NULL, 767: 768: }; 769: 770: 771: struct Intermediary inter = 772: { 773: //m compartment array 774: 775: 2, 776: 777: pcomp, 778: 779: //m all other mathematical components 780: 781: &mca, 782: 783: //m compartment 2 first mechanism number 784: 785: piC2m, 786: }; 787: 788: 789: int main(int argc, char *argv[]) 790: { 791: //- determine intermediary size, and allocate 792: 793: struct MathComponentInfo *pmciCa = MathComponentInfoLookup(pexdecCa[0].mc.iType); 794: 795: struct MathComponentInfo *pmciCaT = MathComponentInfoLookup(pcaiCaT[0].mc.iType); 796: 797: int iChars = 2 * pmciCaT->iChars + 2 * pmciCa->iChars; 798: 799: void *pmc = calloc(sizeof(char), iChars); 800: 801: //- prepare the mechanism intermediary 802: 803: struct ChannelActInact *pcai0 = (struct ChannelActInact *)pmc; 804: 805: *pcai0 = pcaiCaT[0]; 806: 807: struct ExponentialDecay *pexdec0 = (struct ExponentialDecay *)&((char *)pcai0)[pmciCaT->iChars]; 808: 809: *pexdec0 = pexdecCa[0]; 810: 811: struct ChannelActInact *pcai1 = (struct ChannelActInact *)&((char *)pexdec0)[pmciCa->iChars]; 812: 813: *pcai1 = pcaiCaT[1]; 814: 815: struct ExponentialDecay *pexdec1 = (struct ExponentialDecay *)&((char *)pcai1)[pmciCaT->iChars]; 816: 817: *pexdec1 = pexdecCa[1]; 818: 819: //- link the intermediary 820: 821: mca.pmc = pmc; 822: 823: //- do the simulation 824: 825: simulate(argc,argv); 826: } 827: 828: 829: #define main(argc,argv) simulate(argc,argv) 830: 831: //t this prototype can give warning and perhaps errors. 832: 833: int main(int argc, char *argv[]); 834: 835: 836: #include "main.c" 837: 838: