Hotspots of dendritic spine turnover facilitates new spines and NN sparsity (Frank et al 2018)

 Download zip file 
Help downloading and running models
Accession:227087
Model for the following publication: Adam C. Frank, Shan Huang, Miou Zhou, Amos Gdalyahu, George Kastellakis, Panayiota Poirazi, Tawnie K. Silva, Ximiao Wen, Joshua T. Trachtenberg, and Alcino J. Silva Hotspots of Dendritic Spine Turnover Facilitate Learning-related Clustered Spine Addition and Network Sparsity
Reference:
1 . Frank AC, Huang S, Zhou M, Gdalyahu A, Kastellakis G, Silva TK, Lu E, Wen X, Poirazi P, Trachtenberg JT, Silva AJ (2018) Hotspots of dendritic spine turnover facilitate clustered spine addition and learning and memory. Nat Commun 9:422 [PubMed]
Citations  Citation Browser
Model Information (Click on a link to find other models with that property)
Model Type: Neuron or other electrically excitable cell; Connectionist Network;
Brain Region(s)/Organism:
Cell Type(s): Abstract integrate-and-fire leaky neuron with dendritic subunits;
Channel(s):
Gap Junctions:
Receptor(s): NMDA;
Gene(s):
Transmitter(s):
Simulation Environment: C or C++ program; MATLAB;
Model Concept(s): Active Dendrites; Synaptic Plasticity;
Implementer(s): Kastellakis, George [gkastel at gmail.com];
Search NeuronDB for information about:  NMDA;
/
tomodel
data
distributionPlot
exportfig
fig
figs
mtrand
README
.exrc *
an_m_to.m
an_to.m
barwitherr.m *
btagstats.m *
CImg.h *
constructs. *
constructs.cpp *
constructs.h
csvgraph.m
defaults.m
dir2.m *
gconstructs.cpp *
getspikedata.m *
getsynstate.m *
getsynstate2.m *
graphs.m *
hist_percents.m *
hist_with_errs.m *
interact.m *
kurtos.m *
lamodel
lamodel.cpp
LICENSE *
make_graphs.m *
Makefile *
matlab.mat *
mtrand.cpp *
mtrand.h *
multistats.m *
nextplot.m *
pairstrong.m *
repeated.m *
rotateXLabels.m *
run_to.sh
S2sparse.m *
savefig.m *
scratch.m *
sensitivity.m *
stats.m *
stats.py *
stderr.m *
strong2.m *
strongstrong.m *
submit_lamodel.sh *
three.m *
to.cpp
trevrolls.m *
vis.py *
weastrong.m *
wxglmodel *
wxglmodel.cpp *
wxglmodel.h *
wxmodel.cpp *
wxmodel.h *
                            
//
//  Version: $Id: wxmodel.cpp 162 2014-01-08 15:09:14Z gk $
//  Implementation of GUI interface
//
/* 
    Version: $Id: constructs.h 170 2014-01-29 14:00:04Z gk $
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/


#include "constructs.h"
#include "wxmodel.h"


enum {
	MENU_RUN=1,
	MENU_1Hour, 
	MENU_REFRESH,
	MENU_QUIT,
	MENU_CS = 100,
	MENU_CSUS = 300,
	MENU_STRONGTRAIN = 400,
	MENU_INTERSTIM = 500,
	MENU_PROTO = 600,
};



LAWindow::LAWindow(const wxString& title, LANetwork* net) 
	:wxFrame(NULL, wxID_ANY, title, wxDefaultPosition,wxSize(1000, 600))
{
	CreateStatusBar();
	SetStatusText(wxT("Ready"));
	Centre(); 

	this->network = new LANetwork();
	//this->network_panel = new LAPanel(this);
	this->network_panel->network = this->network;
	this->network->wx_window = this;

	//this->network_panel->SetFocus();

	wxMenu* m = new wxMenu;
	m->Append(MENU_RUN, _("&Run"));
	m->Append(MENU_REFRESH, _("Re&fresh"));
	m->Append(MENU_QUIT, _("&Quit"));

	wxMenuBar* mb = new wxMenuBar;
	mb->Append(m,  _("&Simulation"));

	m = new wxMenu;
	for (int i =0; i < network->n_inputs; i++)
		m->Append(MENU_CS+i, wxString::Format(wxT("CS %d"), i));
	mb->Append(m,  _("Run CS"));

	m = new wxMenu;
	for (int i =0; i < network->n_inputs; i++)
		m->Append(MENU_CSUS+i, wxString::Format(wxT("CS+US %d"), i));

	mb->Append(m,  _("Train"));

	m = new wxMenu;
	for (int i =1; i < 5; i++)
		m->Append(MENU_INTERSTIM+i, wxString::Format(wxT("Interstim %d hours"), i));
	mb->Append(m,  _("Interstim"));

	wxString  mprotos[] = {
		wxT("Coallocation Protocol"),
		wxT("Capacity Protocol"), 
	};

	m = new wxMenu;
	for (size_t i =0; i < 2; i++)
	{
		m->Append(MENU_PROTO+i, mprotos[i]);
	}
	mb->Append(m,  _("Protocols"));

	SetMenuBar(mb);
	//Refresh();
}



void LAWindow::OnQuit(wxCommandEvent& ev)
{
	printf("cleaning up... \n");
	this->network->Cleanup();
	Close(true);
	printf("Done\n");
}



/* Menu handlers */
void LAWindow::OnRun(wxCommandEvent& ev)
{
	int id = ev.GetId();
	printf("Running %d!\n", id);

	SetStatusText(wxString::Format(wxT("Wait, running %d..."), id));

	if (id >= MENU_PROTO) // Protocols
	{
		int n = id - MENU_PROTO;
		switch (n)
		{
			case 0:
			{
				this->network->CreateFearNet(100,20, 10, 4);
				for (int i =0;   i < network->n_inputs; i++)
				{
					SetStatusText(wxString::Format(wxT("Training # %d..."), i));
					network->Stimulate(i, 2);
					int mins = 50;
					SetStatusText(wxString::Format(wxT("Waiting %d minutes ..."), mins) );
					network->Interstim(mins*60);
				}
				SetStatusText(wxString::Format(wxT("Waiting 8 Hours...")));
				network->Interstim((60*8)*60);

				FILE* f = fopen("./data/0/memorytest.dat", "w");
				network->enablePlasticity = false;
				network->ResetCrebLevels();

				for (int i =0; i < network->n_inputs; i++)
				{
					SetStatusText(wxString::Format(wxT("Testing # %d..."), i));
					network->Stimulate(i, 1);
					for (nrn_iter ni = network->pyr_list.begin(); ni != network->pyr_list.end(); ++ni)
					{
						fprintf(f ,  "%d  ", (*ni)->total_spikes);
					}
					fprintf(f, "\n");
				}
				

				network->enablePlasticity = true;
				fclose(f);

				f = fopen("./data/0/synweights.txt", "w") ;
				for (syn_iter si = network->synapses.begin(); si != network->synapses.end(); ++si)
				{
					LASynapse* syn = *si;
					if (syn->isPlastic != -1)
						fprintf(f, "%d %d %d %d %f\n", syn->sid, syn->target_branch->bid, syn->target_nrn->nid, syn->source_nrn->input_id, syn->weight); 
				}
				fclose(f);
			}
			break;

			case 1:
			{
				this->network->CreateFearNet(100, 20, 10, 6);
				this->network->RunStoreTest(10, 1, 60, 0);
				printf("Done\n");
				//this->network->StoreDataFiles("./data/0/");
			}		
			break;

			case 2:

			break;

			case 3:
			break;

			case 4:
			break;
		}
	}
	else if (id >= MENU_INTERSTIM)
		network->Interstim((id - MENU_INTERSTIM)*3600);

	else if (id >= MENU_CSUS)
		network->Stimulate( id - MENU_CSUS, 2);

	else if (id >= MENU_CS)
		network->Stimulate( id - MENU_CS, 1);

	SetStatusText(wxT("Done!"));
	printf("Done running\n");
}



void LAPanel::OnTimer(wxCommandEvent& ev)
{

}


void LAPanel::OnClick(wxMouseEvent& e)
{

	/* Find out the nearest clicked neuron, and print properties in the console  */
	for (pt_iterator pi = nrnpoints.begin(); pi != nrnpoints.end(); ++pi)
	{

		wxPoint p = pi->second;

		if ( e.m_x >=p.x && e.m_x <= p.x + 80 && e.m_y <= p.y && e.m_y >= p.y-80)
		{
			int nid = pi->first;
			LANeuron* nrn = network->neurons[nid];
			printf("NID %d (%s) p=%f pr=%f\n", nid, nrn->type == 'I'? "in" :"pyr" , nrn->protein, nrn->proteinRate);

			for (branch_iter bi = nrn->branches.begin(); bi != nrn->branches.end(); ++bi)
			{
				LABranch* b = *bi;
				printf(" branch %d str=%f (tag %f) pb=%f pbr=%f depol=%f\n", b->bid, b->strength, b->strengthTag, b->protein, b->proteinRate, b->depol);
				for (syn_iter si=b->synapses.begin(); si != b->synapses.end(); ++si)
				{
					LASynapse*  s = *si;
					printf("  syn %d from=%d (%d) calc=%f stag=%f eltp=%f w=%f\n", s->sid, s->source_nrn->input_id, s->source_nrn->nid, s->calcium, s->stag, s->eltp, s->weight);
				}

			}


		}

	}
	fflush(stdout);
}



LAPanel::LAPanel(wxFrame* parent)
	: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE | wxFULL_REPAINT_ON_RESIZE)
{


	Connect(wxEVT_PAINT, wxPaintEventHandler(LAPanel::OnPaint));
	Connect(wxEVT_LEFT_UP, wxMouseEventHandler(LAPanel::OnClick));


	hasStarted =0;
}



inline static void colormap1(wxBrush& pen, float value )
{
	pen.SetColour(250, 250-value*200, value*200); 
}


inline static void colormap1(wxPen& pen, float value )
{
	pen.SetColour(value*240.0, 0, 250 - value*200.0);
}


/*
static int palette[][3] = {
	{4, 3,200},
	{4, 200,3},
	{220, 200,1},
	{200, 190,3},
	{255,255,0},
	{255,0,255 },
	{255,0,0 },
	{128,0,0 },
	{192,192,192 },
	{128,128,128 },
	{250, 3,3},
	{0,255,0},
	{128,128,0},
	{200, 190,3},
	{0,128,0},
	{128,0,128},
	{0,255,255},
	{0,128,128},
	{ 50,50,255 },
	{4, 200,3},
};
*/


static wxPoint somap[7] = {
	wxPoint(30, 10),
	wxPoint(30, 10),
	wxPoint(40, 10),
	wxPoint(40, 10),
	wxPoint(40, 10),
	wxPoint(35, 1),
	wxPoint(30, 10)
};



static wxColour pyrcolor(150, 200, 150);
static wxColour incolor(200, 100, 100);
static wxColour syncolor(30, 200, 20);
static wxColour eltpcolor(200, 30, 20);
static wxColour calccolor(20, 30, 200);

static wxColour firecolor(255, 30,30);
static wxColour branchfirecolor(250, 100,30);
static wxPen pen;

void LAPanel::drawPyrCell(wxPaintDC& dc, LANeuron* n, int x , int y)
{
	int nrnheight = this->network->n_branches_per_neuron* 16;
	dc.SetFont(*wxSMALL_FONT);

	pen.SetColour(0,0,0);
	pen.SetStyle(wxCAP_PROJECTING);

	float v = (n->V - (-param_E_L)) / 20.0;
	if (v > 1.0) v = 1.0;
	else if (v  < 0.0) v = 0.0;

	wxColor* nrncolor = &pyrcolor;
	if (n->V > 35.0)
		nrncolor = &firecolor;

	//pen.SetColour(0,0,0);
	dc.SetBrush(wxBrush(*nrncolor, wxSOLID));
	pen.SetColour(*nrncolor);

	pen.SetWidth(3);
	dc.SetPen(pen);

	wxPoint px1(x+60, y);
	wxPoint px2(x+60, y-nrnheight-10);
	dc.DrawLine(px1, px2);

	pen.SetWidth(2);

	dc.SetPen(pen);
	dc.DrawPolygon(7, somap, x+25, y);
	dc.DrawText(wxString::Format(wxT("%f %d  %f"), n->exc_cur, n->total_spikes, n->totcalc), x+50, y+14);

	float yy = y-10;
	int nbr =0;

	for (branch_iter bi = n->branches.begin(); bi != n->branches.end(); ++bi)
	{
		//nbr = 0; // XXX
		LABranch* b = *bi;
		yy -= 15;
		wxPoint pt1(x+60, yy);

		int dx = x+60+56;
		wxPoint pt2(dx, yy);

		if (nbr%2)
		{
			pt2.x = x;
		}

		float hh = b->strength*3.0;
		pen.SetWidth(hh);
		if (b->dspike > 10.0)
			pen.SetColour( branchfirecolor);
		else 
			pen.SetColour( pyrcolor);

		dc.SetPen(pen);
		dc.DrawLine(pt2, pt1);

		dc.DrawText(wxString::Format(wxT("%d  %.3f "),  b->branch_spikes, b->totcalc ), x+110, yy);

		int xxx = x+66;
		if (nbr%2) xxx = x+54;
		int lastinput = -1;

		for (syn_iter si=b->synapses.begin(); si != b->synapses.end(); ++si)
		{
			LASynapse*  s = *si;

			if (s->source_nrn->isSpiking)
			{
				pen.SetColour(firecolor);
			}
			else if (s->source_nrn->input_type == TYPE_CS && s->source_nrn->input_id >=0)
			{
				pen.SetColour(syncolor);
				//pen.SetColour( palette[s->source_nrn->input_id][0], palette[s->source_nrn->input_id][1], palette[s->source_nrn->input_id][2]);
			}
			else
			{
				//continue;
				pen.SetColour(220, 220, 220);
				//pen.SetColour(255.*(s->stag+1.0) / 2.0, 255.*(s->eltp+1.0)/2.0, 200. );
			}


			int space =1;
			if (lastinput == -1) lastinput = s->source_nrn->input_id;
			else if ( s->source_nrn->input_id != lastinput)
			{
				space = 4;
				lastinput = s->source_nrn->input_id;
			}

			if ( nbr%2)
				xxx -= space;
			else
				xxx += space;


			wxPoint sp1(xxx, yy-1);

			int ddd = yy -1 - ( s->weight)*10.0;
			int ddd2 = ddd - (s->stag)*10.0;

			wxPoint sp2(xxx, ddd-1);
			wxPoint sp3(xxx, ddd2-1);
			wxPoint sp4(xxx, ddd2-1 - s->calcium*10.);

			pen.SetWidth(1);
			dc.SetPen(pen);
			dc.DrawLine(sp1, sp2);

			pen.SetColour(eltpcolor);
			dc.SetPen(pen);
			dc.DrawLine(sp2, sp3);

			//pen.SetColour(calccolor);
			//dc.SetPen(pen);
			//dc.DrawLine(sp3, sp4);

		}
		nbr++;
	}
}


void LAPanel::drawInCell(wxPaintDC& dc, LANeuron* n, int x , int y)
{
	int nrnheight = this->network->n_branches_per_neuron* 16;

	pen.SetColour(0,0,0);
	pen.SetStyle(wxCAP_PROJECTING);

	//pen.SetColour(0,0,0);
	wxColor* nrncolor = &incolor;

	if (n->V > 18.)
		nrncolor = &firecolor;

	pen.SetColour( *nrncolor);
	pen.SetWidth(3);
	dc.SetBrush(wxBrush(*nrncolor, wxSOLID));
	dc.SetPen(pen);

	dc.DrawCircle(x+60, y+8, 5);

	wxPoint px1(x+60, y);
	wxPoint px2(x+60, y-nrnheight-10);
	dc.DrawLine(px1, px2);

/*
		if (n->V ==0.0)
			pen.SetColour(240, 100, 20);
		else
			pen.SetColour(20, 180, 20);
*/


	pen.SetWidth(2);
	dc.SetPen(pen);
	//dc.DrawRectangle(x-4, y-4, 8,8);


	dc.DrawText(wxString::Format(wxT("%d"), n->total_spikes), x, y+4);

	//float xx = x;
	float yy = y-10;
	int nbr =0;

	for (branch_iter bi = n->branches.begin(); bi != n->branches.end(); ++bi)
	{
		LABranch* b = *bi;
		yy -= 15;

		//float v = b->depol / 20.0;
		//if (v > 1.0) v = 1.0;
		wxPoint pt1(x+60, yy);

		int dx = x+60+56;
		wxPoint pt2(dx, yy);

		if (nbr%2)
		{
			pt2.x = x;
		}

		//dc.DrawText(wxString::Format(wxT("%d"), b->branch_spikes), x+70, yy-6);
		if (b->strength > 1.0)
			pen.SetWidth( b->strength*1.0);
		else
			pen.SetWidth(1);

		pen.SetColour( *nrncolor);
		dc.SetPen(pen);
		dc.DrawLine(pt2, pt1);

		int xxx = x+66;
		if (nbr%2) xxx = x+54;
		int lastinput = -1;

		for (syn_iter si=b->synapses.begin(); si != b->synapses.end(); ++si)
		{
			LASynapse*  s = *si;

			int space =1;
			if (lastinput == -1) lastinput = s->source_nrn->input_id;
			else if ( s->source_nrn->input_id != lastinput)
			{
				space = 3;
				lastinput = s->source_nrn->input_id;
			}

			if ( nbr%2)
				xxx -= space;
			else
				xxx+= space;


			wxPoint sp1(xxx, yy);

			int ddd = yy - ( s->weight )*7.0;
			wxPoint sp2(xxx, ddd);
			//if (s->source_nrn->V > -10)
			//	pen.SetColour(200.0, 180.0, 0);

			pen.SetColour(200, 200, 200);

			pen.SetWidth(1);
			dc.SetPen(pen);
			dc.DrawLine(sp1, sp2);
		}
		//nbr++;
	}
}


void LAPanel::OnPaint(wxPaintEvent& event)
{
	wxPaintDC dc(this);
	wxSize size = GetClientSize();
	int width = size.GetWidth();
	dc.Clear();
	wxPen pen ;
	wxBrush brush;


	if (!this->network || !this->network->neurons.size()) return;

	int nrnheight = this->network->n_branches_per_neuron* 20;
	int nrnwidth = 160;
	int x = 20;
	int y = nrnheight+40;

	pen.SetColour(0,0,0);
	pen.SetStyle(wxCAP_PROJECTING);

	nrn_iter pc  = network->pyr_list.begin();
	nrn_iter ic = network->in_list.begin();
	int nni =0;

	int totshown =0;
	while(totshown++ < 10)
	{
		if (x+100 >= width)
		{
			x = 20;
			y +=nrnheight+80;
		}

		LANeuron* n;

		if (nni++%5 !=0)
		{
			n = *pc;
			drawPyrCell(dc, n, x, y);
			pc++;
		}
		else
		{

			n = *ic;
			drawInCell(dc, n, x, y);
			ic++;
		}

		nrnpoints[n->nid] = wxPoint(x, y);
		x += nrnwidth;

		if (pc == network->pyr_list.end() || ic == network->in_list.end())
			break;
	}


}





bool LAApp::OnInit()
{
	LAWindow* window = new LAWindow(wxT("LA Model"), NULL);
	//window->network->window = window;
	window->Show(true);
	return true;
}




BEGIN_EVENT_TABLE(LAWindow, wxFrame)

	EVT_MENU(MENU_RUN,  LAWindow::OnRun)
	EVT_MENU_RANGE(MENU_CS, MENU_CS+20,  LAWindow::OnRun)
	//EVT_MENU_RANGE(MENU_CSUS, MENU_CSUS+20,  LAWindow::OnRun)
	EVT_MENU_RANGE(MENU_INTERSTIM, MENU_INTERSTIM+5,  LAWindow::OnRun)
	//EVT_MENU_RANGE(MENU_STRONGTRAIN, MENU_STRONGTRAIN,  LAWindow::OnRun)
	EVT_MENU_RANGE(MENU_PROTO, MENU_PROTO+4,  LAWindow::OnRun)
	EVT_MENU(MENU_QUIT, LAWindow::OnQuit)

END_EVENT_TABLE()




IMPLEMENT_APP(LAApp)