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 <stdlib.h> 20: 21: #include "../../heccer/compartment.h" 22: #include "../../heccer/heccer.h" 23: 24: 25: #define HECCER_TEST_REPORTING_GRANULARITY 100 26: #define HECCER_TEST_STEPS 1000 27: #define HECCER_TEST_TESTED_THINGS ( HECCER_DUMP_VM_COMPARTMENT_MATRIX \ 28: | HECCER_DUMP_VM_COMPARTMENT_DATA \ 29: | HECCER_DUMP_VM_COMPARTMENT_OPERATIONS \ 30: | HECCER_DUMP_VM_CHANNEL_POOL_FLUXES \ 31: | HECCER_DUMP_VM_MECHANISM_DATA \ 32: | HECCER_DUMP_VM_MECHANISM_OPERATIONS \ 33: | HECCER_DUMP_VM_SUMMARY \ 34: ) 35: #define HECCER_TEST_TIME_STEP (1e-6) 36: 37: 38: struct Compartment pcomp[] = 39: { 40: { 41: //m administrative overhead 42: 43: { 44: //m type of structure 45: 46: MATH_TYPE_Compartment, 47: }, 48: 49: //m index of parent compartment, -1 for none 50: 51: -1, 52: 53: /* //m first mechanism */ 54: 55: /* NULL, */ 56: 57: /* //m number of mechanisms */ 58: 59: /* 0, */ 60: 61: //m descriptive values, alphabetical order 62: 63: /* double dCm; */ 64: 65: 4.57537e-11, // unscaled 0.0164, 66: 67: /* double dEm; */ 68: 69: -0.08, 70: 71: /* double dInitVm; */ 72: 73: -0.028, 74: 75: /* double dInject; */ 76: 77: 0, 78: 79: /* double dRa; */ 80: 81: 360502, // unscaled 2.5, 82: 83: /* double dRm; */ 84: 85: 3.58441e+08, // unscaled 1 86: }, 87: 88: { 89: //m administrative overhead 90: 91: { 92: //m type of structure 93: 94: MATH_TYPE_Compartment, 95: }, 96: 97: //m index of parent compartment, -1 for none 98: 99: 0, 100: 101: /* //m first mechanism */ 102: 103: /* NULL, */ 104: 105: /* //m number of mechanisms */ 106: 107: /* 0, */ 108: 109: //m descriptive values, alphabetical order 110: 111: /* double dCm; */ 112: 113: 5.755329373e-12, // unscaled 0.0164, 114: 115: /* double dEm; */ 116: 117: -0.08, 118: 119: /* double dInitVm; */ 120: 121: -0.068, 122: 123: /* double dInject; */ 124: 125: 0, 126: 127: /* double dRa; */ 128: 129: 772813.4375, // unscaled 2.5, 130: 131: /* double dRm; */ 132: 133: 8.548598272e9, // unscaled 3 134: }, 135: }; 136: 137: 138: //v a simple fast sodium channel 139: 140: struct ChannelActInact pcaiCaT[] = 141: { 142: { 143: //m administrative overhead 144: 145: { 146: //m type of structure 147: 148: MATH_TYPE_ChannelActInact, 149: }, 150: 151: //m first set of descriptive values, alphabetical order 152: 153: //m initial reversal potential 154: 155: 0.1375262439, 156: 157: //m get reversal potential from this intermediary, -1 for none 158: 159: -1, 160: 161: //m maximal conductance when all channels are permissive 162: 163: 1.394928884e-08, 164: 165: //m contributes to this concentration pool, -1 for none, boolean indicator only. 166: 167: 1, 168: 169: //m activation description 170: 171: { 172: //m power, for a standard heccer, something between 1 and 4 or so. 173: 174: 1, 175: 176: //m gate definition 177: 178: { 179: //m initial value, commonly forward over backward steady states 180: 181: 0.038918706451336625, 182: 183: //m corresponding index in tables, set to -1 for initialization. 184: 185: -1, 186: 187: { 188: //m forward kinetiks, commonly denoted with alpha or non-perm to perm rate 189: 190: { 191: //m multiplier 192: 193: 2.6e3, 194: 195: //m multiplier membrane dependence, 0.0 for no dependence 196: 197: 0.0, 198: 199: //m 2b: multiplier membrane dependence offset, 0.0 for no dependence 200: 201: 0.0, 202: 203: //m choose between nominator or denominator, 1 means nominator, -1 204: //m means denominator 205: 206: -1.0, 207: 208: //m nominator or denominator offset 209: 210: 1.0, 211: 212: //m membrane offset 213: 214: 0.021, 215: 216: //m denormalized time constant 217: 218: -8e-3, 219: }, 220: 221: //m backward kinetiks, commonly denoted with beta or perm to non-perm rate 222: 223: { 224: //m multiplier 225: 226: 0.18e3, 227: 228: //m multiplier membrane dependence, 0.0 for no dependence 229: 230: 0.0, 231: 232: //m 2b: multiplier membrane dependence offset, 0.0 for no dependence 233: 234: 0.0, 235: 236: //m choose between nominator or denominator, 1 means nominator, -1 237: //m means denominator 238: 239: -1.0, 240: 241: //m nominator or denominator offset 242: 243: 1.0, 244: 245: //m membrane offset 246: 247: 0.04, 248: 249: //m denormalized time constant 250: 251: 4e-3, 252: }, 253: }, 254: }, 255: }, 256: 257: //m inactivation description 258: 259: { 260: //m power, for a standard heccer, something between 1 and 4 or so. 261: 262: 1, 263: 264: //m gate definition 265: 266: { 267: //m initial value, commonly forward over backward steady states 268: 269: 0.082602128127539254, 270: 271: //m corresponding index in tables, set to -1 for initialization. 272: 273: -1, 274: 275: { 276: //m forward kinetiks, commonly denoted with alpha or non-perm to perm rate 277: 278: { 279: //m multiplier 280: 281: 0.0025e3, 282: 283: //m multiplier membrane dependence, 0.0 for no dependence 284: 285: 0.0, 286: 287: //m 2b: multiplier membrane dependence offset, 0.0 for no dependence 288: 289: 0.0, 290: 291: //m choose between nominator or denominator, 1 means nominator, -1 292: //m means denominator 293: 294: -1.0, 295: 296: //m nominator or denominator offset 297: 298: 1.0, 299: 300: //m membrane offset 301: 302: 0.04, 303: 304: //m denormalized time constant 305: 306: 8e-3, 307: }, 308: 309: //m backward kinetiks, commonly denoted with beta or perm to non-perm rate 310: 311: { 312: //m multiplier 313: 314: 0.19e3, 315: 316: //m multiplier membrane dependence, 0.0 for no dependence 317: 318: 0.0, 319: 320: //m 2b: multiplier membrane dependence offset, 0.0 for no dependence 321: 322: 0.0, 323: 324: //m choose between nominator or denominator, 1 means nominator, -1 325: //m means denominator 326: 327: -1.0, 328: 329: //m nominator or denominator offset 330: 331: 1.0, 332: 333: //m membrane offset 334: 335: 0.05, 336: 337: //m denormalized time constant 338: 339: -10.0e-3, 340: }, 341: }, 342: }, 343: }, 344: }, 345: 346: { 347: //m administrative overhead 348: 349: { 350: //m type of structure 351: 352: MATH_TYPE_ChannelActInact, 353: }, 354: 355: //m first set of descriptive values, alphabetical order 356: 357: //m initial reversal potential 358: 359: 0.1470214874, 360: 361: //m get reversal potential from this intermediary, -1 for none 362: 363: -1, 364: 365: //m maximal conductance when all channels are permissive 366: 367: 1.754672296e-09, 368: 369: //m contributes to this concentration pool, -1 for none, boolean indicator only. 370: 371: 3, 372: 373: //m activation description 374: 375: { 376: //m power, for a standard heccer, something between 1 and 4 or so. 377: 378: 1, 379: 380: //m gate definition 381: 382: { 383: //m initial value, commonly forward over backward steady states 384: 385: 0.038918706451336625, 386: 387: //m corresponding index in tables, set to -1 for initialization. 388: 389: -1, 390: 391: { 392: //m forward kinetiks, commonly denoted with alpha or non-perm to perm rate 393: 394: { 395: //m multiplier 396: 397: 2.6e3, 398: 399: //m multiplier membrane dependence, 0.0 for no dependence 400: 401: 0.0, 402: 403: //m 2b: multiplier membrane dependence offset, 0.0 for no dependence 404: 405: 0.0, 406: 407: //m choose between nominator or denominator, 1 means nominator, -1 408: //m means denominator 409: 410: -1.0, 411: 412: //m nominator or denominator offset 413: 414: 1.0, 415: 416: //m membrane offset 417: 418: 0.021, 419: 420: //m denormalized time constant 421: 422: -8e-3, 423: }, 424: 425: //m backward kinetiks, commonly denoted with beta or perm to non-perm rate 426: 427: { 428: //m multiplier 429: 430: 0.18e3, 431: 432: //m multiplier membrane dependence, 0.0 for no dependence 433: 434: 0.0, 435: 436: //m 2b: multiplier membrane dependence offset, 0.0 for no dependence 437: 438: 0.0, 439: 440: //m choose between nominator or denominator, 1 means nominator, -1 441: //m means denominator 442: 443: -1.0, 444: 445: //m nominator or denominator offset 446: 447: 1.0, 448: 449: //m membrane offset 450: 451: 0.04, 452: 453: //m denormalized time constant 454: 455: 4e-3, 456: }, 457: }, 458: }, 459: }, 460: 461: //m inactivation description 462: 463: { 464: //m power, for a standard heccer, something between 1 and 4 or so. 465: 466: 1, 467: 468: //m gate definition 469: 470: { 471: //m initial value, commonly forward over backward steady states 472: 473: 0.082602128127539254, 474: 475: //m corresponding index in tables, set to -1 for initialization. 476: 477: -1, 478: 479: { 480: //m forward kinetiks, commonly denoted with alpha or non-perm to perm rate 481: 482: { 483: //m multiplier 484: 485: 0.0025e3, 486: 487: //m multiplier membrane dependence, 0.0 for no dependence 488: 489: 0.0, 490: 491: //m 2b: multiplier membrane dependence offset, 0.0 for no dependence 492: 493: 0.0, 494: 495: //m choose between nominator or denominator, 1 means nominator, -1 496: //m means denominator 497: 498: -1.0, 499: 500: //m nominator or denominator offset 501: 502: 1.0, 503: 504: //m membrane offset 505: 506: 0.04, 507: 508: //m denormalized time constant 509: 510: 8e-3, 511: }, 512: 513: //m backward kinetiks, commonly denoted with beta or perm to non-perm rate 514: 515: { 516: //m multiplier 517: 518: 0.19e3, 519: 520: //m multiplier membrane dependence, 0.0 for no dependence 521: 522: 0.0, 523: 524: //m 2b: multiplier membrane dependence offset, 0.0 for no dependence 525: 526: 0.0, 527: 528: //m choose between nominator or denominator, 1 means nominator, -1 529: //m means denominator 530: 531: -1.0, 532: 533: //m nominator or denominator offset 534: 535: 1.0, 536: 537: //m membrane offset 538: 539: 0.05, 540: 541: //m denormalized time constant 542: 543: -10.0e-3, 544: }, 545: }, 546: }, 547: }, 548: }, 549: }; 550: 551: 552: struct ExponentialDecay pexdecCa[] = 553: { 554: { 555: //m administrative overhead 556: 557: { 558: //m type of structure 559: 560: MATH_TYPE_ExponentialDecay, 561: }, 562: 563: //m initial value 564: 565: 4e-5, 566: 567: //m beta 568: 569: 7.579027046e+10, 570: 571: //m steady state 572: 573: 4e-05, 574: 575: //m tau 576: 577: 0.00010, 578: 579: //m external contribution delivered by these intermediaries 580: 581: { 582: 0, 583: -1, 584: -1, 585: -1, 586: }, 587: }, 588: 589: { 590: //m administrative overhead 591: 592: { 593: //m type of structure 594: 595: MATH_TYPE_ExponentialDecay, 596: }, 597: 598: //m initial value 599: 600: 4e-5, 601: 602: //m beta 603: 604: 9412391936.0, 605: 606: //m steady state 607: 608: 4e-05, 609: 610: //m tau 611: 612: 0.00020, 613: 614: //m external contribution delivered by these intermediaries 615: 616: { 617: 2, 618: -1, 619: -1, 620: -1, 621: }, 622: } 623: }; 624: 625: 626: int piC2m[] = 627: { 628: 2, 629: 4, 630: -1, 631: }; 632: 633: 634: struct MathComponentArray mca = 635: { 636: //m number of math components 637: 638: 4, 639: 640: //m math component data 641: 642: NULL, 643: 644: //m math component index, initialize to NULL 645: 646: NULL, 647: 648: }; 649: 650: 651: struct Intermediary inter = 652: { 653: //m compartment array 654: 655: 2, 656: 657: pcomp, 658: 659: //m all other mathematical components 660: 661: &mca, 662: 663: //m compartment 2 first mechanism number 664: 665: piC2m, 666: }; 667: 668: 669: int main(int argc, char *argv[]) 670: { 671: //- determine intermediary size, and allocate 672: 673: struct MathComponentInfo *pmciCa = MathComponentInfoLookup(pexdecCa[0].mc.iType); 674: 675: struct MathComponentInfo *pmciCaT = MathComponentInfoLookup(pcaiCaT[0].mc.iType); 676: 677: int iChars = 2 * pmciCaT->iChars + 2 * pmciCa->iChars; 678: 679: void *pmc = calloc(sizeof(char), iChars); 680: 681: //- prepare the mechanism intermediary 682: 683: struct ChannelActInact *pcai0 = (struct ChannelActInact *)pmc; 684: 685: *pcai0 = pcaiCaT[0]; 686: 687: struct ExponentialDecay *pexdec0 = (struct ExponentialDecay *)&((char *)pcai0)[pmciCaT->iChars]; 688: 689: *pexdec0 = pexdecCa[0]; 690: 691: struct ChannelActInact *pcai1 = (struct ChannelActInact *)&((char *)pexdec0)[pmciCa->iChars]; 692: 693: *pcai1 = pcaiCaT[1]; 694: 695: struct ExponentialDecay *pexdec1 = (struct ExponentialDecay *)&((char *)pcai1)[pmciCaT->iChars]; 696: 697: *pexdec1 = pexdecCa[1]; 698: 699: //- link the intermediary 700: 701: mca.pmc = pmc; 702: 703: //- do the simulation 704: 705: simulate(argc,argv); 706: } 707: 708: 709: #define main(argc,argv) simulate(argc,argv) 710: 711: //t this prototype can give warning and perhaps errors. 712: 713: int main(int argc, char *argv[]); 714: 715: 716: #include "main.c" 717: 718: 719: