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