// // 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 . */ #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)