file:/local_home/local_home/hugo/neurospaces_project/heccer/source/c/snapshots/0/addressing.c        (Thu Jul 3 16:50:45 2008 )        HOME


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








































Generated by Xrefactory version 2.0.14 on Thu Jul 24 22:41:20 2008