void CubeMesh::setDiffScale( const CubeMesh* other, vector< VoxelJunction >& ret ) const { for ( vector< VoxelJunction >::iterator i = ret.begin(); i != ret.end(); ++i ) { if ( doubleEq( i->diffScale, 0 ) ) { // Junction across x plane double selfXA = dy_ * dz_; double otherXA = other->dy_ * other->dz_; if ( selfXA <= otherXA ) i->diffScale = 2 * selfXA / ( dx_ + other->dx_ ); else i->diffScale = 2 * otherXA / ( dx_ + other->dx_ ); } else if ( doubleEq( i->diffScale, 1 ) ) { // across y plane double selfXA = dx_ * dz_; double otherXA = other->dx_ * other->dz_; if ( selfXA <= otherXA ) i->diffScale = 2 * selfXA / ( dy_ + other->dy_ ); else i->diffScale = 2 * otherXA / ( dy_ + other->dy_ ); } else if ( doubleEq( i->diffScale, 2 ) ) { // across z plane double selfXA = dx_ * dy_; double otherXA = other->dx_ * other->dy_; if ( selfXA <= otherXA ) i->diffScale = 2 * selfXA / ( dz_ + other->dz_ ); else i->diffScale = 2 * otherXA / ( dz_ + other->dz_ ); } else { assert( 0 ); } } }
void testSetDiffusionAndTransport() { static double test[] = { 0, 2, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 1, 0, }; const unsigned int numCompts = 6; FastMatrixElim fm; fm.makeTestMatrix( test, numCompts ); vector< unsigned int > parentVoxel( numCompts ); parentVoxel[0] = -1; parentVoxel[1] = 0; parentVoxel[2] = 1; parentVoxel[3] = 2; parentVoxel[4] = 3; parentVoxel[5] = 4; // cout << endl; // fm.print(); // cout << endl; // fm.printInternal(); fm.setDiffusionAndTransport( parentVoxel, 1, 10, 0.1 ); // cout << endl; // fm.print(); // cout << endl; // fm.printInternal(); for( unsigned int i =0; i < numCompts; ++i ) { unsigned int start = 0; if ( i > 0 ) start = i - 1; for( unsigned int j = start ; j < i+1 && j < numCompts ; ++j ) { if ( i == j + 1 ) assert( doubleEq( fm.get( i, j ), 0.1 ) ); else if ( i + 1 == j ) { assert( doubleEq( fm.get( i, j ), 2.2 ) ); } else if ( i == j ) { if ( i == 0 ) assert( doubleEq( fm.get( i, j ), 0.8 ) ); else if ( i == numCompts - 1 ) assert( doubleEq( fm.get( i, j ), -0.1 ) ); else assert( doubleEq( fm.get( i, j ), -0.3 ) ); } } } cout << "." << flush; }
PFDD HHChannelBase::selectPower( double power ) { if ( doubleEq( power, 0.0 ) ) return powerN; else if ( doubleEq( power, 1.0 ) ) return power1; else if ( doubleEq( power, 2.0 ) ) return power2; else if ( doubleEq( power, 3.0 ) ) return power3; else if ( doubleEq( power, 4.0 ) ) return power4; else return powerN; }
bool HHChannel::setGatePower( const Eref& e, double power, double *assignee, const string& gateType ) { if ( doubleEq( power, *assignee ) ) return false; if ( doubleEq( *assignee, 0.0 ) && power > 0 ) { createGate( e, gateType ); } else if ( doubleEq( power, 0.0 ) ) { // destroyGate( e, gateType ); } *assignee = power; return true; }
/** * This assumes that diffLength is the quantity to preserve, over numEntries. * So when the compartment changes volume, numEntries changes. diffLength will * be fine-tuned to be a clean multiple. */ void CylMesh::updateCoords( const Eref& e, const vector< double >& concs ) { double temp = sqrt( ( x1_ - x0_ ) * ( x1_ - x0_ ) + ( y1_ - y0_ ) * ( y1_ - y0_ ) + ( z1_ - z0_ ) * ( z1_ - z0_ ) ); if ( doubleEq( temp, 0.0 ) ) { cout << "Error: CylMesh::updateCoords:\n" "total length of compartment = 0 with these parameters\n"; return; } totLen_ = temp; temp = totLen_ / diffLength_; if ( temp < 1.0 ) { diffLength_ = totLen_; numEntries_ = 1; } else { numEntries_ = static_cast< unsigned int >( round ( temp ) ); diffLength_ = totLen_ / numEntries_; } rSlope_ = ( r1_ - r0_ ) / numEntries_; lenSlope_ = diffLength_ * rSlope_ * 2 / ( r0_ + r1_ ); // dx2_[0] = diffLength_; // dx2_[1] = diffLength_; buildStencil(); setChildConcs( e, concs, 0 ); }
void testPoolVolumeScaling() { Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() ); Id comptId = shell->doCreate( "CylMesh", Id(), "cyl", 1 ); Id meshId( comptId.value() + 1 ); Id poolId = shell->doCreate( "Pool", comptId, "pool", 1 ); ObjId mid = shell->doAddMsg( "OneToOne", ObjId( poolId, 0 ), "requestVolume", ObjId( meshId, 0 ), "get_volume" ); assert( mid != ObjId() ); vector< double > coords( 9, 0.0 ); double x1 = 100e-6; double r0 = 10e-6; double r1 = 5e-6; double lambda = x1; coords[3] = x1; coords[6] = r0; coords[7] = r1; coords[8] = lambda; Field< vector< double > >::set( comptId, "coords", coords ); double volume = Field< double >::get( poolId, "volume" ); assert( doubleEq( volume, PI * x1 * (r0+r1) * (r0+r1) / 4.0 ) ); Field< double >::set( poolId, "n", 400 ); double volscale = 1 / ( NA * volume ); double conc = Field< double >::get( poolId, "conc" ); assert( doubleEq( conc, 400 * volscale ) ); Field< double >::set( poolId, "conc", 500 * volscale ); double n = Field< double >::get( poolId, "n" ); assert( doubleEq( n, 500 ) ); Field< double >::set( poolId, "nInit", 650 ); double concInit = Field< double >::get( poolId, "concInit" ); assert( doubleEq( concInit, 650 * volscale ) ); Field< double >::set( poolId, "concInit", 10 * volscale ); n = Field< double >::get( poolId, "nInit" ); assert( doubleEq( n, 10 ) ); shell->doDelete( comptId ); cout << "." << flush; }
void testMMenz() { Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() ); Id mmid = shell->doCreate( "MMenz", Id(), "mm", 1 ); // mmenz MMenz m; ProcInfo p; m.vSetKm( mmid.eref(), 5.0 ); m.vSetKcat( mmid.eref(), 4.0 ); m.vReinit( mmid.eref(), &p ); m.vSub( 2 ); m.vEnz( 3 ); assert( doubleEq( m.vGetKm( mmid.eref() ), 5.0 ) ); assert( doubleEq( m.vGetKcat( mmid.eref() ), 4.0 ) ); m.vProcess( mmid.eref(), &p ); shell->doDelete( mmid ); cout << "." << flush; }
void testReacVolumeScaling() { Shell* shell = reinterpret_cast< Shell* >( Id().eref().data() ); Id comptId = shell->doCreate( "CubeMesh", Id(), "cube", 1 ); Id meshId( comptId.value() + 1 ); Id subId = shell->doCreate( "Pool", comptId, "sub", 1 ); Id prdId = shell->doCreate( "Pool", comptId, "prd", 1 ); Id reacId = shell->doCreate( "Reac", comptId, "reac", 1 ); double vol1 = 1e-15; ObjId mid = shell->doAddMsg( "OneToOne", subId, "requestVolume", meshId, "get_volume" ); assert( mid != ObjId() ); mid = shell->doAddMsg( "OneToOne", prdId, "requestVolume", meshId, "get_volume" ); assert( mid != ObjId() ); vector< double > coords( 9, 10.0e-6 ); coords[0] = coords[1] = coords[2] = 0; Field< vector< double > >::set( comptId, "coords", coords ); double volume = Field< double >::get( comptId, "volume" ); assert( doubleEq( volume, vol1 ) ); ObjId ret = shell->doAddMsg( "Single", reacId, "sub", subId, "reac" ); assert( ret != ObjId() ); ret = shell->doAddMsg( "Single", reacId, "prd", prdId, "reac" ); assert( ret != ObjId() ); Field< double >::set( reacId, "Kf", 2 ); Field< double >::set( reacId, "Kb", 3 ); double x = Field< double >::get( reacId, "kf" ); assert( doubleEq( x, 2 ) ); x = Field< double >::get( reacId, "kb" ); assert( doubleEq( x, 3 ) ); ret = shell->doAddMsg( "Single", reacId, "sub", subId, "reac" ); assert( ret != ObjId() ); double conv = 1.0 / ( NA * vol1 ); x = Field< double >::get( reacId, "kf" ); assert( doubleEq( x, 2 * conv ) ); x = Field< double >::get( reacId, "kb" ); assert( doubleEq( x, 3 ) ); ret = shell->doAddMsg( "Single", reacId, "sub", subId, "reac" ); assert( ret != ObjId() ); ret = shell->doAddMsg( "Single", reacId, "prd", prdId, "reac" ); assert( ret != ObjId() ); x = Field< double >::get( reacId, "kf" ); assert( doubleEq( x, 2 * conv * conv ) ); x = Field< double >::get( reacId, "kb" ); assert( doubleEq( x, 3 * conv ) ); shell->doDelete( comptId ); cout << "." << flush; }
Interpol2D::Interpol2D( unsigned int xdivs, double xmin, double xmax, unsigned int ydivs, double ymin, double ymax ) : xmin_( xmin ), xmax_( xmax ), ymin_( ymin ), ymax_( ymax ), sy_( 1.0 ) { resize( xdivs+1, ydivs+1 ); if ( !doubleEq( xmax_, xmin ) ) invDx_ = xdivs / ( xmax_ - xmin_); else invDx_ = 1.0; if ( !doubleEq( ymax_, ymin ) ) invDy_ = ydivs / ( ymax_ - ymin_); else invDy_ = 1.0; }
void SynChan::normalizeGbar() { if ( doubleEq( tau2_, 0.0 ) ) { // norm_ = 1.0; norm_ = SynChanBase::getGbar(); } else { if ( doubleEq( tau1_, tau2_ ) ) { norm_ = SynChanBase::getGbar() * SynE() / tau1_; } else { double tpeak = tau1_ * tau2_ * log( tau1_ / tau2_ ) / ( tau1_ - tau2_ ); norm_ = SynChanBase::getGbar() * ( tau1_ - tau2_ ) / ( tau1_ * tau2_ * ( exp( -tpeak / tau1_ ) - exp( -tpeak / tau2_ ) )); } } if ( normalizeWeights_ && getNumSynapses() > 0 ) norm_ /= static_cast< double >( getNumSynapses() ); }
bool HHChannel2D::setGatePower( const Eref& e, const Qinfo* q, double power, double *assignee, const string& gateType ) { if ( power < 0 ) { cout << "Error: HHChannel2D::set" << gateType << "power: Cannot use negative power: " << power << endl; return 0; } if ( doubleEq( power, *assignee ) ) return 0; if ( doubleEq( *assignee, 0.0 ) && power > 0 ) { createGate( e, q, gateType ); } else if ( doubleEq( power, 0.0 ) ) { destroyGate( e, q, gateType ); } *assignee = power; return 1; }
void MarkovRateTable::updateRates() { double temp; unsigned int i,j; //Update 1D rates, if any. for( unsigned int k = 0; k < listOf1dRates_.size(); ++k ) { j = ( listOf1dRates_[k] % 10 ) - 1; i = ( ( listOf1dRates_[k] / 10 ) % 10 ) - 1; temp = Q_[i][j]; if ( isRateLigandDep( i, j ) ) Q_[i][j] = lookup1dValue( i, j, ligandConc_ ); else { Q_[i][j] = lookup1dValue( i, j, Vm_ ); } //Ensures that the row sums to zero. if ( !doubleEq( temp, Q_[i][j] ) ) Q_[i][i] = Q_[i][i] - Q_[i][j] + temp; } //Update 2D rates, if any. for( unsigned int k = 0; k < listOf2dRates_.size(); ++k ) { j = ( listOf2dRates_[k] % 10 ) - 1; i = ( ( listOf2dRates_[k] / 10 ) % 10 ) - 1; temp = Q_[i][j]; Q_[i][j] = lookup2dValue( i, j, Vm_, ligandConc_ ); //Ensures that the row sums to zero. if ( !doubleEq( temp, Q_[i][j] ) ) Q_[i][i] = Q_[i][i] - Q_[i][j] + temp; } }
void Interpol2D::setDx( double value ) { if ( !doubleEq( value, 0.0 ) ) { unsigned int xdivs = static_cast< unsigned int >( 0.5 + fabs( xmax_ - xmin_ ) / value ); if ( xdivs < 1 || xdivs > MAX_DIVS ) { cerr << "Error: Interpol2D::localSetDx Out of range:" << xdivs + 1 << " entries in table.\n"; return; } resize( xdivs + 1, 0 ); } }
void SynChan::normalizeGbar() { if ( doubleEq( tau2_, 0.0 ) ) { // norm_ = 1.0; norm_ = ChanCommon::getGbar(); } else { if ( doubleEq( tau1_, tau2_ ) ) { norm_ = ChanCommon::getGbar() * SynE() / tau1_; } else { double tpeak = tau1_ * tau2_ * log( tau1_ / tau2_ ) / ( tau1_ - tau2_ ); norm_ = ChanCommon::getGbar() * ( tau1_ - tau2_ ) / ( tau1_ * tau2_ * ( exp( -tpeak / tau1_ ) - exp( -tpeak / tau2_ ) )); } } /* * Can't handle at this time. Simple but tedious to implement. if ( normalizeWeights_ && getNumSynapses() > 0 ) norm_ /= static_cast< double >( getNumSynapses() ); */ }
/* * Note that this causes issues if we have variable dt. */ void SynChan::reinit( const Eref& e, ProcPtr info ) { double dt = info->dt; activation_ = 0.0; modulation_ = 1.0; SynChanBase::setGk( 0.0 ); SynChanBase::setIk( 0.0 ); X_ = 0.0; Y_ = 0.0; // These below statements are also called when setting tau1 and tau2 // (required when changing tau1 and tau2 during a simulation). xconst1_ = tau1_ * ( 1.0 - exp( -dt / tau1_ ) ); xconst2_ = exp( -dt / tau1_ ); if ( doubleEq( tau2_, 0.0 ) ) { yconst1_ = 1.0; yconst2_ = 0.0; } else { yconst1_ = tau2_ * ( 1.0 - exp( -dt / tau2_ ) ); yconst2_ = exp( -dt / tau2_ ); } normalizeGbar(); /* if ( doubleEq( tau2_, 0.0 ) ) { yconst1_ = 1.0; yconst2_ = 0.0; norm_ = 1.0; } else { yconst1_ = tau2_ * ( 1.0 - exp( -dt / tau2_ ) ); yconst2_ = exp( -dt / tau2_ ); if ( tau1_ == tau2_ ) { norm_ = SynChanBase::getGbar() * SynE() / tau1_; } else { double tpeak = tau1_ * tau2_ * log( tau1_ / tau2_ ) / ( tau1_ - tau2_ ); norm_ = SynChanBase::getGbar() * ( tau1_ - tau2_ ) / ( tau1_ * tau2_ * ( exp( -tpeak / tau1_ ) - exp( -tpeak / tau2_ ) )); } } // updateNumSynapse( e ); if ( normalizeWeights_ && getNumSynapses() > 0 ) norm_ /= static_cast< double >( getNumSynapses() ); */ // while ( !pendingEvents_.empty() ) // pendingEvents_.pop(); SynChanBase::reinit(e, info); }
void Interpol2D::setSy( double value ) { if ( !doubleEq( value, 0.0 ) ) { double ratio = value / sy_; vector< vector< double > >::iterator i; vector< double >::iterator j; for ( i = table_.begin(); i != table_.end(); i++ ) for ( j = i->begin(); j != i->end(); j++ ) *j *= ratio; sy_ = value; } else { cerr << "Error: Interpol2D::localSetSy: sy too small:" << value << "\n"; } }
void testFuncTerm() { FuncTerm ft; ft.setExpr( "x0 + x1 * t" ); double args[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; // First check that it doesn't die even if we forget to set up anything. double ans = ft( args, 2.0 ); vector< unsigned int > mol( 2, 0 ); mol[0] = 2; mol[1] = 0; ft.setReactantIndex( mol ); ans = ft( args, 10.0 ); assert( doubleEq( ans, 13.0 ) ); mol[0] = 0; mol[1] = 9; ft.setReactantIndex( mol ); ans = ft( args, 2.0 ); assert( doubleEq( ans, 21.0 ) ); cout << "." << flush; }
/** * \todo Later do interpolation etc to preserve contents. * \todo Later also check that it is OK for xmax_ < xmin_ */ void Interpol2D::setDy( double value ) { if ( !doubleEq( value, 0.0 ) ) { unsigned int ydivs = static_cast< unsigned int >( 0.5 + fabs( ymax_ - ymin_ ) / value ); if ( ydivs < 1 || ydivs > MAX_DIVS ) { cerr << "Error: Interpol2D::localSetDy Out of range:" << ydivs + 1 << " entries in table.\n"; return; } setYdivs( ydivs ); invDy_ = ydivs / ( ymax_ - ymin_ ); } }
void testTaperingCylDiffn() { Shell* s = reinterpret_cast< Shell* >( Id().eref().data() ); double len = 25e-6; double r0 = 2e-6; double r1 = 1e-6; double diffLength = 1e-6; // 1e-6 is the highest dx for which error is OK double runtime = 10.0; double dt = 0.1; // 0.2 is the highest dt for which the error is in bounds double diffConst = 1.0e-12; // Should set explicitly, currently during creation of DiffPoolVec //double diffConst = 1.0e-12; Id model = s->doCreate( "Neutral", Id(), "model", 1 ); Id cyl = s->doCreate( "CylMesh", model, "cyl", 1 ); Field< double >::set( cyl, "r0", r0 ); Field< double >::set( cyl, "r1", r1 ); Field< double >::set( cyl, "x0", 0 ); Field< double >::set( cyl, "x1", len ); Field< double >::set( cyl, "diffLength", diffLength ); unsigned int ndc = Field< unsigned int >::get( cyl, "numMesh" ); assert( ndc == static_cast< unsigned int >( round( len / diffLength ))); Id pool = s->doCreate( "Pool", cyl, "pool", 1 ); Field< double >::set( pool, "diffConst", diffConst ); Id dsolve = s->doCreate( "Dsolve", model, "dsolve", 1 ); Field< Id >::set( dsolve, "compartment", cyl ); s->doUseClock( "/model/dsolve", "process", 1 ); s->doSetClock( 1, dt ); // Next: build by setting the path of the dsolve. Field< string >::set( dsolve, "path", "/model/cyl/pool" ); // Then find a way to test it. assert( pool.element()->numData() == ndc ); Field< double >::set( ObjId( pool, 0 ), "nInit", 1.0 ); s->doReinit(); s->doStart( runtime ); double myTot = 0.0; vector< double > poolVec; Field< double >::getVec( pool, "n", poolVec ); for ( unsigned int i = 0; i < poolVec.size(); ++i ) { myTot += poolVec[i]; } assert( doubleEq( myTot, 1.0 ) ); s->doDelete( model ); cout << "." << flush; }
void SynChan::setTau2( double tau2 ) { tau2_ = tau2; // Aditya added // required if changing tau1 during a simulation // (eg. Marder pyloric networks). if ( doubleEq( tau2_, 0.0 ) ) { yconst1_ = 1.0; yconst2_ = 0.0; } else { yconst1_ = tau2_ * ( 1.0 - exp( -dt_ / tau2_ ) ); yconst2_ = exp( -dt_ / tau2_ ); } normalizeGbar(); }
/* * Note that this causes issues if we have variable dt. */ void SynChan::vReinit( const Eref& e, ProcPtr info ) { dt_ = info->dt; activation_ = 0.0; ChanBase::setGk( e, 0.0 ); ChanBase::setIk( e, 0.0 ); X_ = 0.0; Y_ = 0.0; // These below statements are also called when setting tau1 and tau2 // (required when changing tau1 and tau2 during a simulation). xconst1_ = tau1_ * ( 1.0 - exp( -dt_ / tau1_ ) ); xconst2_ = exp( -dt_ / tau1_ ); if ( doubleEq( tau2_, 0.0 ) ) { yconst1_ = 1.0; yconst2_ = 0.0; } else { yconst1_ = tau2_ * ( 1.0 - exp( -dt_ / tau2_ ) ); yconst2_ = exp( -dt_ / tau2_ ); } normalizeGbar(); sendReinitMsgs(e, info); }
void testCylDiffnWithStoich() { Shell* s = reinterpret_cast< Shell* >( Id().eref().data() ); double len = 25e-6; double r0 = 1e-6; double r1 = 1e-6; double diffLength = 1e-6; // 1e-6 is the highest dx for which error is OK double runtime = 10.0; double dt0 = 0.1; // Used for diffusion. 0.2 is the highest dt for which the error is in bounds double dt1 = 1; // Used for chem. double diffConst = 1.0e-12; Id model = s->doCreate( "Neutral", Id(), "model", 1 ); Id cyl = s->doCreate( "CylMesh", model, "cyl", 1 ); Field< double >::set( cyl, "r0", r0 ); Field< double >::set( cyl, "r1", r1 ); Field< double >::set( cyl, "x0", 0 ); Field< double >::set( cyl, "x1", len ); Field< double >::set( cyl, "diffLength", diffLength ); unsigned int ndc = Field< unsigned int >::get( cyl, "numMesh" ); assert( ndc == static_cast< unsigned int >( round( len / diffLength ))); Id pool1 = s->doCreate( "Pool", cyl, "pool1", 1 ); Id pool2 = s->doCreate( "Pool", cyl, "pool2", 1 ); Field< double >::set( pool1, "diffConst", diffConst ); Field< double >::set( pool2, "diffConst", diffConst/2 ); Id stoich = s->doCreate( "Stoich", model, "stoich", 1 ); Id ksolve = s->doCreate( "Ksolve", model, "ksolve", 1 ); Id dsolve = s->doCreate( "Dsolve", model, "dsolve", 1 ); Field< Id >::set( stoich, "compartment", cyl ); Field< Id >::set( stoich, "ksolve", ksolve ); Field< Id >::set( stoich, "dsolve", dsolve ); Field< string >::set( stoich, "path", "/model/cyl/#" ); assert( pool1.element()->numData() == ndc ); // Then find a way to test it. vector< double > poolVec; Field< double >::set( ObjId( pool1, 0 ), "nInit", 1.0 ); Field< double >::set( ObjId( pool2, 0 ), "nInit", 1.0 ); Field< double >::getVec( pool1, "nInit", poolVec ); assert( poolVec.size() == ndc ); assert( doubleEq( poolVec[0], 1.0 ) ); assert( doubleEq( poolVec[1], 0.0 ) ); vector< double > nvec = LookupField< unsigned int, vector< double > >::get( dsolve, "nVec", 0); assert( nvec.size() == ndc ); // Next: build by doing reinit s->doUseClock( "/model/dsolve", "process", 0 ); s->doUseClock( "/model/ksolve", "process", 1 ); s->doSetClock( 0, dt0 ); s->doSetClock( 1, dt1 ); s->doReinit(); s->doStart( runtime ); nvec = LookupField< unsigned int, vector< double > >::get( dsolve, "nVec", 0); Field< double >::getVec( pool1, "n", poolVec ); assert( nvec.size() == poolVec.size() ); for ( unsigned int i = 0; i < nvec.size(); ++i ) assert( doubleEq( nvec[i], poolVec[i] ) ); /* cout << endl; for ( unsigned int i = 0; i < nvec.size(); ++i ) cout << nvec[i] << " "; cout << endl; */ double dx = diffLength; double err = 0.0; double analyticTot = 0.0; double myTot = 0.0; for ( unsigned int i = 0; i < nvec.size(); ++i ) { double x = i * dx + dx * 0.5; // This part is the solution as a func of x,t. double y = dx * // This part represents the init n of 1 in dx ( 1.0 / sqrt( PI * diffConst * runtime ) ) * exp( -x * x / ( 4 * diffConst * runtime ) ); err += ( y - nvec[i] ) * ( y - nvec[i] ); //cout << i << " " << x << " " << y << " " << conc[i] << endl; analyticTot += y; myTot += nvec[i]; } assert( doubleEq( myTot, 1.0 ) ); // cout << "analyticTot= " << analyticTot << ", myTot= " << myTot << endl; assert( err < 1.0e-5 ); s->doDelete( model ); cout << "." << flush; }
//Simple tests on whether the exponential lookup tables are being set //to the correct size and the lookup function tests. //Cannot test the interpolation routines here as there is not matrix //exponential method in the base class. //testMarkovSolver() defined in MarkovSolver.cpp contains this test. void testMarkovSolverBase() { const Cinfo* rateTableCinfo = MarkovRateTable::initCinfo(); const Cinfo* interpol2dCinfo = Interpol2D::initCinfo(); const Cinfo* vectorTableCinfo = VectorTable::initCinfo(); const Cinfo* solverBaseCinfo = MarkovSolverBase::initCinfo(); Id vecTableId = Id::nextId(); Id int2dId = Id::nextId(); vector< Id > rateTableIds; vector< Id > solverBaseIds; vector< Element* > rateTableElements; vector< Eref* > rateTableErefs; vector< Element* > solverBaseElements; vector< Eref* > solverBaseErefs; vector< MarkovRateTable* > rateTables; vector< MarkovSolverBase* > solverBases; vector< DimInfo > single; string str; unsigned int numCopies = 4; for ( unsigned int i = 0; i < numCopies; ++i ) { rateTableIds.push_back( Id::nextId() ); str = string("ratetable") + static_cast< char >( 65 + i ); rateTableElements.push_back( new Element( rateTableIds[i], rateTableCinfo, str, single, 1 ) ); rateTableErefs.push_back( new Eref( rateTableElements[i], 0 ) ); rateTables.push_back( reinterpret_cast< MarkovRateTable* >( rateTableErefs[i]->data() ) ); solverBaseIds.push_back( Id::nextId() ); str = string("solverbase") + static_cast< char >( 65 + i ); solverBaseElements.push_back( new Element( solverBaseIds[i], solverBaseCinfo, str, single, 1 ) ); solverBaseErefs.push_back( new Eref( solverBaseElements[i], 0 ) ); solverBases.push_back( reinterpret_cast< MarkovSolverBase* >( solverBaseErefs[i]->data() ) ); } Element *eInt2d = new Element( int2dId, interpol2dCinfo, "int2d", single, 1 ); Element *eVecTable = new Element( vecTableId, vectorTableCinfo, "vecTable", single, 1 ); Interpol2D *int2dTable; VectorTable* vecTable; Eref int2dEref( eInt2d, 0 ); int2dTable = reinterpret_cast< Interpol2D* >( int2dEref.data() ); Eref vecTableEref( eVecTable, 0 ); vecTable = reinterpret_cast< VectorTable* >( vecTableEref.data() ); ////////////////////////////// //ratetables[0] //Only 2D rates. //ratetables[1] //1D and 2D rates. //ratetables[2] //Only ligand dependent rates. //ratetables[3] //Only voltage dependent rates. ////////////////////////////// //////// //Case 1 : //Rates (1,2) and (2,3) are ligand and voltage dependent. /////// rateTables[0]->init( 3 ); setupInterpol2D( int2dTable, 201, -0.05, 0.10, 151, 1e-9, 50e-9 ); rateTables[0]->setInt2dChildTable( 1, 2, int2dId ); setupInterpol2D( int2dTable, 175, -0.02, 0.19, 151, 3e-9, 75e-9 ); rateTables[0]->setInt2dChildTable( 2, 3, int2dId ); solverBases[0]->init( rateTableIds[0], 0.1 ); assert( solverBases[0]->getXdivs() == 201 ); assert( doubleEq( solverBases[0]->getXmin(), -0.05 ) ); assert( doubleEq( solverBases[0]->getXmax(), 0.19 ) ); assert( solverBases[0]->getYdivs() == 151 ); //1D and 2D rates. rateTables[1]->init( 5 ); /////// //Case 2 : //Rates (1,2) and (1,3) are ligand and voltage dependent. //Rates (2,1) and (3,1) are voltage and ligand dependent respectively. ////// setupInterpol2D( int2dTable, 250, -0.10, 0.75, 101, 10e-9, 25e-8 ); rateTables[1]->setInt2dChildTable( 1, 2, int2dId ); setupInterpol2D( int2dTable, 275, -0.05, 0.55, 141, 5e-9, 40e-7 ); rateTables[1]->setInt2dChildTable( 1, 3, int2dId ); //Voltage dependent. setupVectorTable( vecTable, 145, -0.17, 0.73 ); rateTables[1]->setVtChildTable( 2, 1, vecTableId, 0 ); //Ligand dependent setupVectorTable( vecTable, 375, 7e-9, 75e-7 ); rateTables[1]->setVtChildTable( 3, 1, vecTableId, 1 ); solverBases[1]->init( rateTableIds[1], 0.1 ); assert( solverBases[1]->getXdivs() == 275 ); assert( solverBases[1]->getYdivs() == 375 ); assert( doubleEq( solverBases[1]->getXmin(), -0.17 ) ); assert( doubleEq( solverBases[1]->getXmax(), 0.75 ) ); assert( doubleEq( solverBases[1]->getYmin(), 5e-9 ) ); assert( doubleEq( solverBases[1]->getYmax(), 75e-7 ) ); //////// //Case 3 : Only ligand dependent rates. //Rates (1, 2), (3, 5), (2, 4), (4, 1). /////// rateTables[2]->init( 5 ); setupVectorTable( vecTable, 155, 7e-9, 50e-9 ); rateTables[2]->setVtChildTable( 1, 2, vecTableId, 1 ); setupVectorTable( vecTable, 190, 4e-9, 35e-9 ); rateTables[2]->setVtChildTable( 3, 5, vecTableId, 1 ); setupVectorTable( vecTable, 120, 7e-9, 90e-9 ); rateTables[2]->setVtChildTable( 2, 4, vecTableId, 1 ); setupVectorTable( vecTable, 250, 10e-9, 100e-9 ); rateTables[2]->setVtChildTable( 4, 1, vecTableId, 1 ); solverBases[2]->init( rateTableIds[2], 0.1 ); assert( doubleEq( 1e-308 * solverBases[2]->getYmin(), 1e-308 * DBL_MAX ) ); assert( doubleEq( 1e308 * solverBases[2]->getYmax(), 1e308 * DBL_MIN ) ); assert( solverBases[2]->getYdivs() == 0u ); assert( doubleEq( solverBases[2]->getXmin(), 4e-9 ) ); assert( doubleEq( solverBases[2]->getXmax(), 100e-9 ) ); assert( solverBases[2]->getXdivs() == 250 ); /////// //Case 4 : Only voltage dependent rates. //Rates (3,6), (5, 6), (1, 4). ////// rateTables[3]->init( 7 ); setupVectorTable( vecTable, 100, -0.05, 0.1 ); rateTables[3]->setVtChildTable( 3, 6, vecTableId, 1 ); setupVectorTable( vecTable, 190, -0.15, 0.2 ); rateTables[3]->setVtChildTable( 5, 6, vecTableId, 1 ); setupVectorTable( vecTable, 140, -0.2, 0.1 ); rateTables[3]->setVtChildTable( 1, 4, vecTableId, 1 ); solverBases[3]->init( rateTableIds[3], 0.1 ); assert( doubleEq( 1e-308 * solverBases[3]->getYmin(), 1e-308 * DBL_MAX ) ); assert( doubleEq( 1e308 * solverBases[3]->getYmax(), 1e308 * DBL_MIN ) ); assert( solverBases[3]->getYdivs() == 0u ); assert( doubleEq( solverBases[3]->getXmin(), -0.2 ) ); assert( doubleEq( solverBases[3]->getXmax(), 0.2 ) ); assert( solverBases[3]->getXdivs() == 190 ); for ( unsigned int i = 0; i < numCopies; ++i ) { rateTableIds[i].destroy(); solverBaseIds[i].destroy(); delete rateTableErefs[i]; delete solverBaseErefs[i]; } int2dId.destroy(); vecTableId.destroy(); cout << "." << flush; }
int main() { Board<Tile> b; std::ofstream file; // set files file.open(test_land_filename); file << test_land_data; file.close(); file.open(test_hare_filename); file << test_hare_data; file.close(); file.open(test_puma_filename); file << test_puma_data; file.close(); BoardSetter::set_land_from_file(b,test_land_filename); BoardSetter::set_hare_from_file(b,test_hare_filename); BoardSetter::set_puma_from_file(b,test_puma_filename); for(size_t x=0; x<b.get_width(); ++x) for(size_t y=0; y<b.get_height(); ++y) { // test land if(x == 0 || x == b.get_width()-1 || y == 0 || y == b.get_height()-1) { if(b(x,y).is_land()) { std::cout << "Land padding not working" << std::endl; return 1; } } else if(b(x,y).is_land() != (test_land_array[y-1][x-1] == 1)) { std::cout << "land array not properly set" << std::endl; std::cout << b(x,y).is_land() << ", " << test_land_array[y-1][x-1] << std::endl; return 1; } // test hare if(x == 0 || x == b.get_width()-1 || y == 0 || y == b.get_height()-1) { if(!doubleEq(b(x,y).hare, 0)) { std::cout << "Hare padding not working" << std::endl; return 1; } } else if(!doubleEq(b(x,y).hare, test_hare_array[y-1][x-1])) { std::cout << "hare array not properly set" << std::endl; std::cout << b(x,y).hare << ", " << test_hare_array[y-1][x-1] << std::endl; return 1; } // test puma if(x == 0 || x == b.get_width()-1 || y == 0 || y == b.get_height()-1) { if(!doubleEq(b(x,y).puma, 0)) { std::cout << "Puma padding not working" << std::endl; return 1; } } else if(!doubleEq(b(x,y).puma, test_puma_array[y-1][x-1])) { std::cout << "puma array not properly set" << std::endl; return 1; } } // all tests passed! return 0; }
void testCellDiffn() { Id makeCompt( Id parentCompt, Id parentObj, string name, double len, double dia, double theta ); Shell* s = reinterpret_cast< Shell* >( Id().eref().data() ); double len = 40e-6; double dia = 10e-6; double diffLength = 1e-6; double dt = 1.0e-1; double runtime = 100.0; double diffConst = 1.0e-12; Id model = s->doCreate( "Neutral", Id(), "model", 1 ); Id soma = makeCompt( Id(), model, "soma", dia, dia, 90 ); Id dend = makeCompt( soma, model, "dend", len, 3e-6, 0 ); Id branch1 = makeCompt( dend, model, "branch1", len, 2e-6, 45.0 ); Id branch2 = makeCompt( dend, model, "branch2", len, 2e-6, -45.0 ); Id twig1 = makeCompt( branch1, model, "twig1", len, 1.5e-6, 90.0 ); Id twig2 = makeCompt( branch1, model, "twig2", len, 1.5e-6, 0.0 ); Id nm = s->doCreate( "NeuroMesh", model, "neuromesh", 1 ); Field< double >::set( nm, "diffLength", diffLength ); Field< string >::set( nm, "geometryPolicy", "cylinder" ); Field< Id >::set( nm, "cell", model ); unsigned int ns = Field< unsigned int >::get( nm, "numSegments" ); assert( ns == 6 ); unsigned int ndc = Field< unsigned int >::get( nm, "numDiffCompts" ); assert( ndc == 210 ); Id pool1 = s->doCreate( "Pool", nm, "pool1", 1 ); Field< double >::set( pool1, "diffConst", diffConst ); Id pool2 = s->doCreate( "Pool", nm, "pool2", 1 ); Field< double >::set( pool2, "diffConst", diffConst ); Id dsolve = s->doCreate( "Dsolve", model, "dsolve", 1 ); Field< Id >::set( dsolve, "compartment", nm ); s->doUseClock( "/model/dsolve", "process", 1 ); s->doSetClock( 1, dt ); // Next: build by setting path Field< string >::set( dsolve, "path", "/model/neuromesh/pool#" ); vector< double > nvec = LookupField< unsigned int, vector< double > >::get( dsolve, "nVec", 0); assert( nvec.size() == ndc ); assert( pool1.element()->numData() == ndc ); Field< double >::set( ObjId( pool1, 0 ), "nInit", 1.0 ); Field< double >::set( ObjId( pool2, ndc - 1 ), "nInit", 2.0 ); s->doReinit(); s->doStart( runtime ); nvec = LookupField< unsigned int, vector< double > >::get( dsolve, "nVec", 0); vector< double > pool1Vec; Field< double >::getVec( pool1, "n", pool1Vec ); assert( pool1Vec.size() == ndc ); vector< double > pool2Vec; Field< double >::getVec( pool2, "n", pool2Vec ); assert( pool2Vec.size() == ndc ); double myTot1 = 0; double myTot2 = 0; for ( unsigned int i = 0; i < nvec.size(); ++i ) { assert( doubleEq( pool1Vec[i], nvec[i] ) ); myTot1 += nvec[i]; myTot2 += pool2Vec[i]; } assert( doubleEq( myTot1, 1.0 ) ); assert( doubleEq( myTot2, 2.0 ) ); /* cout << endl; cout << "Big cell: " << endl; for ( unsigned int i = 0; i < nvec.size(); ++i ) cout << nvec[i] << ", " << pool2Vec[i] << endl; cout << endl; */ s->doDelete( model ); cout << "." << flush; }
void testCalcJunction() { Shell* s = reinterpret_cast< Shell* >( Id().eref().data() ); // Make a neuron with same-size dend and spine. PSD is tiny. // Put a, b, c in dend, b, c, d in spine, c, d, f in psd. No reacs. // See settling of all concs by diffusion, pairwise. Id model = s->doCreate( "Neutral", Id(), "model", 1 ); Id dend = s->doCreate( "Compartment", model, "dend", 1 ); Id neck = s->doCreate( "Compartment", model, "spine_neck", 1 ); Id head = s->doCreate( "Compartment", model, "spine_head", 1 ); Field< double >::set( dend, "x", 10e-6 ); Field< double >::set( dend, "diameter", 2e-6 ); Field< double >::set( dend, "length", 10e-6 ); Field< double >::set( neck, "x0", 9e-6 ); Field< double >::set( neck, "x", 9e-6 ); Field< double >::set( neck, "y", 1e-6 ); Field< double >::set( neck, "diameter", 0.5e-6 ); Field< double >::set( neck, "length", 1.0e-6 ); Field< double >::set( head, "x0", 9e-6 ); Field< double >::set( head, "x", 9e-6 ); Field< double >::set( head, "y0", 1e-6 ); Field< double >::set( head, "y", 11e-6 ); Field< double >::set( head, "diameter", 2e-6 ); Field< double >::set( head, "length", 10e-6 ); s->doAddMsg( "Single", ObjId( dend ), "raxial", ObjId( neck ), "axial"); s->doAddMsg( "Single", ObjId( neck ), "raxial", ObjId( head ), "axial"); Id nm = s->doCreate( "NeuroMesh", model, "nm", 1 ); Field< double >::set( nm, "diffLength", 10e-6 ); Field< bool >::set( nm, "separateSpines", true ); Id sm = s->doCreate( "SpineMesh", model, "sm", 1 ); Id pm = s->doCreate( "PsdMesh", model, "pm", 1 ); ObjId mid = s->doAddMsg( "Single", ObjId( nm ), "spineListOut", ObjId( sm ), "spineList" ); assert( !mid.bad() ); mid = s->doAddMsg( "Single", ObjId( nm ), "psdListOut", ObjId( pm ), "psdList" ); Field< Id >::set( nm, "cell", model ); vector< Id > pools( 9 ); static string names[] = {"a", "b", "c", "b", "c", "d", "c", "d", "e" }; static Id parents[] = {nm, nm, nm, sm, sm, sm, pm, pm, pm}; for ( unsigned int i = 0; i < 9; ++i ) { pools[i] = s->doCreate( "Pool", parents[i], names[i], 1 ); assert( pools[i] != Id() ); Field< double >::set( pools[i], "concInit", 1.0 + 1.0 * i ); Field< double >::set( pools[i], "diffConst", 1e-11 ); if ( i < 6 ) { double vol = Field< double >::get( pools[i], "volume" ); assert( doubleEq( vol, 10e-6 * 1e-12 * PI ) ); } } Id dendsolve = s->doCreate( "Dsolve", model, "dendsolve", 1 ); Id spinesolve = s->doCreate( "Dsolve", model, "spinesolve", 1 ); Id psdsolve = s->doCreate( "Dsolve", model, "psdsolve", 1 ); Field< Id >::set( dendsolve, "compartment", nm ); Field< Id >::set( spinesolve, "compartment", sm ); Field< Id >::set( psdsolve, "compartment", pm ); Field< string >::set( dendsolve, "path", "/model/nm/#" ); Field< string >::set( spinesolve, "path", "/model/sm/#" ); Field< string >::set( psdsolve, "path", "/model/pm/#" ); assert( Field< unsigned int >::get( dendsolve, "numAllVoxels" ) == 1 ); assert( Field< unsigned int >::get( spinesolve, "numAllVoxels" ) == 1 ); assert( Field< unsigned int >::get( psdsolve, "numAllVoxels" ) == 1 ); assert( Field< unsigned int >::get( dendsolve, "numPools" ) == 3 ); assert( Field< unsigned int >::get( spinesolve, "numPools" ) == 3 ); assert( Field< unsigned int >::get( psdsolve, "numPools" ) == 3 ); SetGet2< Id, Id >::set( dendsolve, "buildNeuroMeshJunctions", spinesolve, psdsolve ); s->doSetClock( 0, 0.01 ); s->doUseClock( "/model/#solve", "process", 0 ); s->doReinit(); s->doStart( 100 ); for ( unsigned int i = 0; i < 9; ++i ) { double c = Field< double >::get( pools[i], "conc" ); double n = Field< double >::get( pools[i], "n" ); double v = Field< double >::get( pools[i], "volume" ); cout << pools[i].path() << ": " << c << ", " << n << ", " << n / v << ", " << v << endl; } s->doDelete( model ); cout << "." << flush; }