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