// Basic Neural Simulation Framework (BSNF)
//
// Copyright 2007 John L Baker. All rights reserved.
//
// This software is provided AS IS under the terms of the Open Source
// MIT License. See http://www.opensource.org/licenses/mit-license.php.
//
// File: test_baker_670.cpp
//
// Release: 1.0.1
// Author: John Baker
// Updated: 6 March 2007
//
// Description:
//
// Simulate regular mouse movement and generated inputs.
// Results are written to files for visualization.
//
// A traing DG cells supplies the initial place cell
// location. During the test, ACh is set to an initial
// level and then changed over time (1 sec intervals).
// ACh levels do not go below the final value specified.
//
// For this test the maze is rectangular and the path
// followed is parallel with maze walls. This allows
// place field characteristics in a linear track to
// be simulated.
//
// A warning is in order if whole cell voltage probing
// is done. Over 1 gigabyte is generated per 5 minutes
// of simulated time. Obviously this can add up quickly
// for longer runs.
#include <iostream>
#include <ctime>
#include "bnsf.h"
#include "mouse_baker_2003.h"
using namespace std;
using namespace BNSF;
using namespace UOM;
using namespace BAKER_2003;
void test_baker_670()
{
cout<<"Test case 670 - linear track place cells with decreasing ACh"<<endl;
int seedIndex=0; // random number seed index (0 to 4)
double trainingDuration = 9*minute;
double noveltyDuration = 6*minute;
double phaseProbeDuration = 3*minute;
double completionProbeDuration = 3*minute;
Number initialACh = 50*microM;
Number finalACh = 20*microM;
Number deltaACh = (initialACh-finalACh)/(noveltyDuration);
Number currentACh;
// Selective knockout switches
bool koNMDARCurrent = false;
bool koNMDARPlasticity = false;
bool koNMDARAChMod = false;
bool koNMDARCaDepSupp = false;
bool koThetaPhasePrecession = false;
// Other control switches and params
bool useTeacherCell = true;
bool disablePlasticityForProbe = true;
bool chgDGThetaPhaseToMatchCA3 = false;
bool disableTheta = false;
bool probeVm = false;
bool probeCa = false;
bool varySpeedForProbe = false;
Number secondaryProbeSpeed = 5*cm/sec;
// Simulation objects
Controller* cont = new Controller;
Maze* maze = new RectangularMaze;
Mouse* mouse = new Mouse(maze,
Mouse::wallFollower,
Mouse::defaultSeeds(seedIndex));
PlaceCell* pc; // current place cell (for debug access)
int k;
time_t startTime,endTime;
double diffTime;
double t;
time(&startTime);
// Set up external recorders to capture results
ExternalRecorder* mouseStateRecorder = new ExternalStateRecorder("test-baker-mouse-states.txt");
ExternalRecorder* cellVoltageRecorder = new ExternalVoltageRecorder("test-baker-voltages.txt");
ExternalRecorder* cellCalciumRecorder = new ExternalCalciumRecorder("test-baker-calcium.txt");
ExternalRecorder* cellSpikeRecorder = new ExternalSpikeRecorder("test-baker-spikes.txt");
ExternalRecorder* dendSpikeRecorder = new ExternalDendriteSpikeRecorder("test-baker-dendrite-spikes.txt");
ExternalRecorder* ECSpikeRecorder = new ExternalSpikeRecorder("test-baker-ec-spikes.txt");
ExternalRecorder* DGSpikeRecorder = new ExternalSpikeRecorder("test-baker-dg-spikes.txt");
ExternalRecorder* CA3SpikeRecorder = new ExternalSpikeRecorder("test-baker-ca3-spikes.txt");
ExternalRecorder* INSpikeRecorder = new ExternalSpikeRecorder("test-baker-in-spikes.txt");
ExternalRecorder* subsetSpikeRecorder = new ExternalSpikeRecorder("test-baker-subset-spikes.txt");
ExternalRecorder* cellACSynapseRecorder =
new ExternalSynapseRecorder("test-baker-ac-synapse-weights.txt","AC_GluR");
cellACSynapseRecorder->minInterval(10*sec);
ExternalRecorder* cellPPSynapseRecorder =
new ExternalSynapseRecorder("test-baker-pp-synapse-weights.txt","PP_GluR");
cellPPSynapseRecorder->minInterval(10*sec);
// Show statistics
mouse->printSynapseCounts();
// Save place cell centers
mouse->ECPlaceCells()->printPlaceFieldCenters("test-baker-ec-pcloc.txt");
mouse->DGPlaceCells()->printPlaceFieldCenters("test-baker-dg-pcloc.txt");
mouse->CA3PlaceCells()->printPlaceFieldCenters("test-baker-ca3-pcloc.txt");
// Hook up the mouse
mouse->addToController(cont);
mouse->addProbe(mouseStateRecorder);
// Add a spike recorder probe to all layers
mouse->ECPlaceCells()->addProbeToAll(ECSpikeRecorder);
mouse->DGPlaceCells()->addProbeToAll(DGSpikeRecorder);
mouse->CA3PlaceCells()->addProbeToAll(CA3SpikeRecorder);
mouse->CA3AxoAxonicCells()->addProbeToAll(INSpikeRecorder);
mouse->CA3BasketCells()->addProbeToAll(INSpikeRecorder);
mouse->CA3BistratifiedCells()->addProbeToAll(INSpikeRecorder);
mouse->CA3OLMCells()->addProbeToAll(INSpikeRecorder);
// Debug ODE solver performance (or not)
mouse->targetCell()->solver()->debugPerformance(false);
// Add probes to target cell
mouse->targetCell()->addProbe(cellSpikeRecorder);
mouse->targetCell()->addProbe(dendSpikeRecorder);
mouse->targetCell()->addProbe(subsetSpikeRecorder);
mouse->targetCell()->addProbe(cellACSynapseRecorder);
mouse->targetCell()->addProbe(cellPPSynapseRecorder);
// Optional probe of voltage and calcium
if (probeVm) {
mouse->targetCell()->addProbe(cellVoltageRecorder);
}
if (probeCa) {
mouse->targetCell()->addProbe(cellCalciumRecorder);
}
// Add probes to selected cells for ease of plotting
for (k=1;k<=200;k++) {
pc=mouse->ECPlaceCells()->placeCell(k);
pc->addProbe(subsetSpikeRecorder);
}
for (k=1;k<=200;k++) {
pc=mouse->DGPlaceCells()->placeCell(k);
pc->addProbe(subsetSpikeRecorder);
}
for (k=1;k<=200;k++) {
pc=mouse->CA3PlaceCells()->placeCell(k);
pc->addProbe(subsetSpikeRecorder);
}
// Perform any selective NMDAR knockouts
mouse->targetCell()->knockoutNMDAR(
koNMDARCurrent,
koNMDARPlasticity,
koNMDARAChMod,
koNMDARCaDepSupp );
// If requested, disable theta phase precession
if (koThetaPhasePrecession) {
mouse->ECPlaceCells()->disableThetaPhasePrecession();
mouse->DGPlaceCells()->disableThetaPhasePrecession();
mouse->CA3PlaceCells()->disableThetaPhasePrecession();
}
// If requested, change DG theta phase to match CA3
if (chgDGThetaPhaseToMatchCA3) {
Number CA3ThetaPhase = mouse->CA3PlaceCells()->placeCell(1)->thetaPhase();
for (k=1;k<=mouse->DGPlaceCells()->numCells();k++) {
pc=mouse->DGPlaceCells()->placeCell(k);
pc->thetaPhase(CA3ThetaPhase);
}
}
// If requested, set theta amplitude to zero suppressing theta.
if (disableTheta) {
cout<<"Setting theta amplitudes to zero"<<endl;
mouse->ECPlaceCells()->thetaAmplitude(0);
mouse->DGPlaceCells()->thetaAmplitude(0);
mouse->CA3PlaceCells()->thetaAmplitude(0);
mouse->CA3AxoAxonicCells()->thetaAmplitude(0);
mouse->CA3BasketCells()->thetaAmplitude(0);
mouse->CA3BistratifiedCells()->thetaAmplitude(0);
mouse->CA3OLMCells()->thetaAmplitude(0);
}
// Progress report
time(&endTime);
diffTime = difftime(endTime,startTime);
cout<<endl;
cout<<"Time to build layers (sec) = "<<diffTime<<endl;
cout<<"Simulated trainging duration (sec) = "<<trainingDuration/sec<<endl;
cout<<"Simulated phase probe duration (sec) = "<<phaseProbeDuration/sec<<endl;
cout<<"Simulated completion probe duration (sec) = "<<completionProbeDuration/sec<<endl;
cout<<"Knockout flags = "
<< koNMDARCurrent
<< koNMDARPlasticity
<< koNMDARAChMod
<< koNMDARCaDepSupp
<< koThetaPhasePrecession
<< endl;
cout<<"Vary speed for a 2nd phase probe pass = "<<varySpeedForProbe<<endl;
cout<<"Random number seed index = "<<seedIndex<<endl;
// Run the simulation
cout<<endl;
cout<<"Simulation starting"<<endl;
cont->start();
if (useTeacherCell) {
// Pick one DG cell as the training input and make it active
// Start by making possible afferent DG cells inactive.
mouse->DGPlaceCells()->setActivity(false,1,50);
mouse->DGPlaceCells()->placeCell(21)->setCenter(0*cm,-17.5*cm);
mouse->DGPlaceCells()->placeCell(21)->isActive( true );
}
// Set training pass ACh Level
currentACh = initialACh;
mouse->targetCell()->AChLevel(currentACh);
cout<<"Initial ACh Level (microM) = "<<mouse->targetCell()->AChLevel()/microM<<endl;
cout<<"Final ACh Level (microM) = "<<finalACh/microM<<endl;
// Run the training interval simulation
cout<<"time (sec)=";
for (t=0;t<trainingDuration;t+=1*sec) {
// Run for 1 sec
cout<<t<<" ";
cont->runForDuration(1*sec);
// Set new ACh level
currentACh = maxval(currentACh-deltaACh,finalACh);
mouse->targetCell()->AChLevel(currentACh);
if (int(t)%10==9) {
cout<<" ACh="<<mouse->targetCell()->AChLevel()/microM<<endl;
}
}
cout<<endl;
// Run the probe pass simulations using current ACh levels
cout<<"Simulation continuing - phase probe pass"<<endl;
// Perform any selective NMDAR knockouts.
mouse->targetCell()->knockoutNMDAR(
koNMDARCurrent,
disablePlasticityForProbe,
koNMDARAChMod,
koNMDARCaDepSupp );
// Run for more time
cout<<"time (sec)=";
for (t=0;t<phaseProbeDuration;t+=1*sec) {
cout<<t<<" ";
if (int(t)%10==9) cout<<endl;
cont->runForDuration(1*sec);
}
cout<<endl;
if (varySpeedForProbe) {
Number oldSpeed=mouse->speed();
// Set a new speed
mouse->speed(secondaryProbeSpeed);
// Run the probe pass simulations using current ACh levels
cout<<"Phase probe continuing - movement speed = "
<<secondaryProbeSpeed / (cm/sec)<<" cm/sec"
<<endl;
// Run for more time
cout<<"time (sec)=";
for (t=0;t<phaseProbeDuration;t+=1*sec) {
cout<<t<<" ";
if (int(t)%10==9) cout<<endl;
cont->runForDuration(1*sec);
}
cout<<endl;
// Restore the original speed
mouse->speed(oldSpeed);
}
// Run the probe pass simulations using current ACh levels
cout<<"Simulation continuing - pattern completion probe pass"<<endl;
cout<<"Plasticity disabled for probe = " <<disablePlasticityForProbe<<endl;
// Perform any selective NMDAR knockouts.
mouse->targetCell()->knockoutNMDAR(
koNMDARCurrent,
disablePlasticityForProbe,
koNMDARAChMod,
koNMDARCaDepSupp );
// Make the training inputs inactive for the probe
mouse->DGPlaceCells()->setActivity(false,1,50);
// Run for more time
cout<<"time (sec)=";
for (t=0;t<completionProbeDuration;t+=1*sec) {
cout<<t<<" ";
if (int(t)%10==9) cout<<endl;
cont->runForDuration(1*sec);
}
cout<<endl;
// Wrap up
cont->runForDuration(1*msec); // ensure final synapse reports
cout<<"Simulation ending"<<endl;
cout<<"Derivative evaluations = "
<<mouse->targetCell()->solver()->derivativeEvals()<<endl;
cout<<"Time steps done = "
<<mouse->targetCell()->solver()->timeStepsDone()<<endl;
cont->finish();
time(&endTime);
diffTime = difftime(endTime,startTime);
cout<<"Time to execute (sec) = "<<diffTime<<endl;
// Delete allocated objects. Doing it this way
// allows debugging if something goes wrong.
cout<<"Deleting data structures"<<endl;
delete mouse;
delete cont;
delete maze;
delete mouseStateRecorder;
delete cellVoltageRecorder;
delete cellCalciumRecorder;
delete cellSpikeRecorder;
delete dendSpikeRecorder;
delete ECSpikeRecorder;
delete DGSpikeRecorder;
delete CA3SpikeRecorder;
delete INSpikeRecorder;
delete subsetSpikeRecorder;
delete cellACSynapseRecorder;
delete cellPPSynapseRecorder;
cout<<"Done"<<endl;
}