コード例 #1
0
Symbol COMPONENT_CLASS_CPP::event(Event* event)
{
	switch(event->type)
	{
		case EVENT_STATE_SET:
		{
		
			//	extract DataML
			EventStateSet* data = (EventStateSet*) event->data;
			XMLNode xmlNode(data->state);
			DataMLNode nodeState(&xmlNode);
			
			// obtain the parameters
			values = nodeState.getField("values").getArrayDOUBLE();
	
			return C_OK;


		}

		// CREATE THE PORTS
		case EVENT_INIT_CONNECT:
		{
		
			//	on first call
			if (event->flags & F_FIRST_CALL)
			{
			
				out.setName("out");
				out.create(hComponent);
				out.setStructure(TYPE_DOUBLE | TYPE_REAL, Dims(values.size()).cdims());

			}

			//	on last call
			if (event->flags & F_LAST_CALL)
			{
			}

			//	ok
			return C_OK;
		}

		case EVENT_RUN_SERVICE:
		{

	
			out.setContent(&(values[0]));
									
			//	ok
			return C_OK;
		}

	}

	//	if we service the event, we return C_OK
	//	if we don't, we should return S_NULL to indicate that we didn't
	return S_NULL;
}
コード例 #2
0
void COMPONENT_CLASS_CPP::event(Event& event)
{
	switch(event.type)
	{
		// Stepping event comes first
		case EVENT_RUN_SERVICE:
		{
			// create data structures
			DOUBLE* idata;
			vector<VDOUBLE> totals;
			VDOUBLE neg_total;
			Symbol hInput;
			VDOUBLE odata;
			odata.resize(count, 0);
			totals.resize(hSets.size());
			for (UINT32 i=0; i<totals.size(); i++) {
				totals[i].resize(count,0);
			}
			neg_total.resize(count,0);
			
			// get noise
			VDOUBLE noise_membrane;
			noise_membrane.resize(count);
			for (UINT32 i=0; i < count; i++) {
				// decay membrane
				membrane[i] *= lambda_membrane[i];
			}
			
			dev_std_util_rng::fill(hComponent,rng, &noise_membrane[0], count, 1.0, 0.0);
			
			
			// get data and assign based on operation
			for (UINT32 i=0; i < hInputs.size(); i++) {
				for (UINT32 j=0; j < numPorts[i]; j++) {
					Symbol input = iif.getData(hInputs[i][j]);
					// make up the totals according to the operation types
					idata = (DOUBLE*)numeric_get_content(input);
					for (UINT32 k=0; k < count; k++) {
						if (i == ADD && idata[k] < 0) {neg_total[k] += idata[k];}
						else {totals[i][k] += idata[k];}
						// don't let shunt be negative!
						if (i == SHUNT && j == (hInputs[i].size() - 1) && totals[i][k] < -p_v[k]) {
							totals[i][k] = -p_v[k];
						}
					}
				}
			}
			
			// do it
			for (UINT32 i=0; i < count; i++) {
				if (!SINGLE_ISINF(pos_reversal_potential[i])) {
					totals[ADD][i] *= (pos_reversal_potential[i] - membrane[i]);
				}
				if (!SINGLE_ISINF(neg_reversal_potential[i])) {
					neg_total[i] *= (membrane[i] - neg_reversal_potential[i]);
				}
				totals[ADD][i] += neg_total[i];
				
				/* ####################################################### */
				// combine operation types

				odata[i] = totals[ADD][i];
				
				// Only do other operations if we have the ports
				if (hInputs[SHUNT].size() > 0) odata[i] *= (p_v[i] + totals[SHUNT][i]);

				if (hInputs[SHUNT_DEV].size() > 0) odata[i] /= (p_v[i] + totals[SHUNT_DEV][i]);

				//
				/* ####################################################### */
				
				odata[i] *=  lambda_membrane_reciprocal[i];
				membrane[i] += odata[i];
				membrane[i] += noise_membrane[i] * sigma_membrane[i];
			}
	

			numeric_set_content(oif.getData(hOutput), &membrane[0]);
			
			event.response = C_OK;
			return;
		}

		case EVENT_INIT_CONNECT:
		{
			// open output port with dimensions given by the state data
			if (event.flags & F_FIRST_CALL)
			{
			
				hOutput = oif.addPort("dev/std/data/numeric", 0);
				oif.setPortName(hOutput, "out");
				Symbol out = oif.getData(hOutput);
				numeric_set_structure(out, TYPE_DOUBLE | TYPE_REAL, dims);
				
			}
			
			// check inputs for veracity...
			if (event.flags & F_LAST_CALL)
			{
				Symbol hInput;
				for (UINT32 i=0; i<iif.getNumberOfPorts(); i++) {
					hInput = (iif.getPort(i));
					/*Symbol data = iif.getData(hInput);
					assertClass(data, "dev/std/data/numeric");
   					numeric_validate(data, TYPE_DOUBLE);*/
				}
			}

			
			// check input dimensions against state data
				/*Dims srcDims = cppdims(structure);
			if (srcDims[0] != src.dims[0] || srcDims[1] != src.dims[1]) {berr << "Source dimensions of input do not match dims";}
			}*/

			event.response = C_OK;
			return;
		}
		
		
		case EVENT_INIT_POSTCONNECT:
		{	
			// get the ports for the different sets
			hInputs.resize(hSets.size());
			for (UINT32 i=0; i < hSets.size(); i++) {
				numPorts.push_back(iif.getNumberOfPorts(hSets[i]));
				for (UINT32 j=0; j < numPorts[i]; j++) {
					hInputs[i].push_back(iif.getPort(hSets[i], j));
				}
			}
			// assume ports on the default set are addition and add them to that list
			numPorts[0] += iif.getNumberOfPorts();
			for (UINT32 i=0; i < iif.getNumberOfPorts(); i++) {
				hInputs[0].push_back(iif.getPort(i));
			}
			
			event.response = C_OK;
			return;
			
		}
		
		
		case EVENT_STATE_SET:
		{
			/* ######################################################### */
			// create operation sets
			hSets.push_back(iif.getSet("add"));
			hSets.push_back(iif.getSet("shunt"));
			hSets.push_back(iif.getSet("shunt_dev"));
				
			/* ######################################################### */
			
			//	create and seed RNG
			rng = coreCreateUtility(hComponent, "dev/std/util/rng", 0);
			dev_std_util_rng::select(hComponent, rng, "MT2000.normal");
			dev_std_util_rng::seed(hComponent, rng, &(*event.state.seed)[0], event.state.seed->size());
			
			/*
				Extracting the data from the state MatML file - reality checking as we go...
			*/
			
			
			MatMLNode nodePars(event.xmlNode);
			
			// get dimensions
			VUINT64 dims_temp = nodePars.getField("dims").getArrayUINT64();
			for (UINT32 i=0; i < dims_temp.size(); i++) {
				dims.push_back(dims_temp[i]);
			}
			
			count = dims.getNumberOfElements();
			
			membrane.resize(count, 0);
			
			// get the args
			if (nodePars.hasField("tau_membrane")) {
				tau_membrane = nodePars.getField("tau_membrane").getArraySINGLE();
			}
			UINT32 N = tau_membrane.size();
			
			if (nodePars.hasField("sigma_membrane")) {
				sigma_membrane = nodePars.getField("sigma_membrane").validate(Dims(N)).getArraySINGLE();
			}
			
			if (nodePars.hasField("p")) {
				p_v = nodePars.getField("p").validate(Dims(N)).getArraySINGLE();
			}
			
			if (nodePars.hasField("pos_reversal_potential")) {
				pos_reversal_potential = nodePars.getField("pos_reversal_potential").validate(Dims(N)).getArraySINGLE();
			}
			
			if (nodePars.hasField("neg_reversal_potential")) {
				neg_reversal_potential = nodePars.getField("neg_reversal_potential").validate(Dims(N)).getArraySINGLE();
			}
			
			lambda_membrane.resize(count);
			lambda_membrane_reciprocal.resize(count);
			if (N == 1) {
				tau_membrane.resize(count, tau_membrane[0]);
				sigma_membrane.resize(count, sigma_membrane[0]);
				p_v.resize(count, p_v[0]);
				pos_reversal_potential.resize(count, pos_reversal_potential[0]);
				neg_reversal_potential.resize(count, neg_reversal_potential[0]);
			}
			else if (N != count) {
				berr << "pars are of incorrect size!";
			}
			
			for (UINT32 i=0; i<count; i++) {
				lambda_membrane[i] = exp(-1.0 / (tau_membrane[i] * sampleRateToRate(time.sampleRate)));
				lambda_membrane_reciprocal[i] = 1.0 - lambda_membrane[i];
			}
			
			
			//	ok
			event.response = C_OK;
			return;
		}


//#include "events.cpp"


	}

	//	raise an exception if you run into trouble during event(). the return value
	//	indicates whether you processed the event.


	
}
コード例 #3
0
Symbol COMPONENT_CLASS_CPP::event(Event* event)
{
	switch(event->type)
	{
		case EVENT_STATE_SET:
		{
			//	extract DataML
			EventStateSet* data = (EventStateSet*) event->data;
			XMLNode xmlNode(data->state);
			DataMLNode nodeState(&xmlNode);

			// obtain the parameters
			VDOUBLE size = nodeState.getField("sizeIn").getArrayDOUBLE();
			numElementsIn = 1;
			for (unsigned int i = 0; i < size.size(); ++i) {
				numElementsIn *= size[i];
			}

			size = nodeState.getField("sizeOut").getArrayDOUBLE();
			numElementsOut = 1;
			for (unsigned int i = 0; i < size.size(); ++i) {
				numElementsOut *= size[i];
			}

			string binpath = nodeState.getField("binpath").getSTRING();

                        bool _has_delay = false;

			// get the connectivity
			if (nodeState.hasField("_bin_file_name")) {

				string fileName = nodeState.getField("_bin_file_name").getSTRING();
				int _num_conn = (int) nodeState.getField("_bin_num_conn").getDOUBLE();
				_has_delay = (bool) nodeState.getField("_bin_has_delay").getDOUBLE();

				// open the file for reading
				FILE * binfile;
				// FIXME: We really need an absolute path here, generated at runtime
				fileName = binpath + fileName;
				binfile = fopen(fileName.c_str(),"rb");
				if (!binfile) {
					// That failed; try the default location for
					// spineml-2-brahms on a Unix system:
					fileName = "~/spineml-2-brahms/model/" + fileName;
					binfile = fopen(fileName.c_str(),"rb");
					if (!binfile) {
						berr << "Could not open connectivity file";
					}
				}

                                VDOUBLE delayForConnTemp;

				srcInds.resize(_num_conn);
				dstInds.resize(_num_conn);
				if (_has_delay) {
                                    delayForConnTemp.resize(_num_conn);
                                }
				for (int i_BRAHMS = 0; i_BRAHMS < _num_conn; ++i_BRAHMS) {
                                    size_t v = fread(&srcInds[i_BRAHMS], sizeof(unsigned int), 1, binfile);
				    if (v == 0) {
                                        bout << "Read 0 bytes from binfile" << D_INFO;
                                        if (ferror(binfile)) {
                                            berr << "Error reading sources";
                                        }
				    }
                                    v = fread(&dstInds[i_BRAHMS], sizeof(unsigned int), 1, binfile);
				    if (v == 0) {
                                        bout << "2. Read 0 bytes from binfile" << D_INFO;
                                        if (ferror(binfile)) {
                                            berr << "Error reading destinations";
                                        }
				    }
                                    if (_has_delay) {
                                        v = fread(&delayForConnTemp[i_BRAHMS], sizeof(unsigned int), 1, binfile);
                                        if (v == 0) {
                                            if (ferror(binfile)) {
                                                berr << "ferror. read " << v << " uints from " << fileName << " for delayForConnTemp[" << i_BRAHMS << "]";
                                            }
                                            if (feof(binfile)) {
                                                berr << "feof trying to read delayForConnTemp[" << i_BRAHMS << "]";
                                            }
                                            berr << "read " << v << " uints from " << fileName << " for delayForConnTemp[" << i_BRAHMS << "]";
                                        }
                                    }
				}
			} else {
				srcInds = nodeState.getField("src").getArrayINT32();
				dstInds = nodeState.getField("dst").getArrayINT32();
			}

			if (srcInds.size() != dstInds.size())
				berr << "Connectivity src and dst lists have different sizes";

			// sanity check
			for (UINT32 i = 0; i < srcInds.size(); ++i) {
				if (srcInds[i] >= numElementsIn) {
                                    berr << "Index out of range for connection : srcInds[" << i << "] (" << srcInds[i] << ") >= numElementsIn ("<< numElementsIn <<")";
				}
				if (dstInds[i] >= numElementsOut) {
                                    berr << "Index out of range for connection : dstInds[" << i << "] (" << dstInds[i] << ") >= numElementsOut ("<< numElementsOut <<")";
				}
			}

			if (_has_delay) {
                            berr << "Unfortunately, delays in Generic inputs are not supported by SpineML_2_BRAHMS." << D_WARN;
			}

			spikesIn = false;
			impulseIn = false;
			portFound = false;

			return C_OK;


		}

		// CREATE THE PORTS
		case EVENT_INIT_CONNECT:
		{

			//	on each call
			int numInputs = iif.getNumberOfPorts();

			if (numInputs == 1 && portFound == false) {
				portFound = true;

				if (in.tryAttach(hComponent, "in")) {
					out.setName("out");
					out.create(hComponent);
					out.setStructure(TYPE_DOUBLE | TYPE_REAL, Dims(numElementsOut).cdims());
				}
				if (ins.tryAttach(hComponent,"inSpike")) {
					spikesIn = true;
					outs.setName("out");
					outs.create(hComponent);
					outs.setCapacity(numElementsIn*numElementsOut);

					// create lookup for spikes
					spikeInds.resize(numElementsIn);
					for (UINT32 i = 0; i < srcInds.size(); ++i) {
						spikeInds[srcInds[i]].push_back(dstInds[i]);
					}

				}
				if (ini.tryAttach(hComponent,"inImpulse")) {
					impulseIn = true;
					outi.setName("out");
					outi.create(hComponent);
					outi.setCapacity(numElementsIn*numElementsOut*3);

					// create lookup for spikes
					spikeInds.resize(numElementsIn);
					for (UINT32 i = 0; i < srcInds.size(); ++i) {
						spikeInds[srcInds[i]].push_back(dstInds[i]);
					}

				}

			}

			//	on last call
			if (event->flags & F_LAST_CALL)
			{
			}

			//	ok
			return C_OK;
		}

		case EVENT_RUN_SERVICE:
		{
			if (!spikesIn && !impulseIn) {
				DOUBLE * inData;
				inData = (DOUBLE*) in.getContent();

				DOUBLE * outData;
				outData = (DOUBLE *) out.getContent();

				// clear old data
				memset(outData, 0, 8*numElementsOut);

				for (UINT32 i = 0; i < srcInds.size(); ++i) {
					outData[dstInds[i]] += inData[srcInds[i]];
				}
			}
			if (spikesIn)
			{
				INT32 * spikeData;
				UINT32 numSpikes;
				numSpikes = ins.getContent(spikeData);

				VINT32 outData;
				// for each input spike
				for (UINT32 i = 0; i < numSpikes; ++i) {
					// for each target of the source of that spike
					for (UINT32 j = 0; j < spikeInds[spikeData[i]].size(); ++j) {
						// add output spike to the list
						outData.push_back(spikeInds[spikeData[i]][j]);
					}
				}


				outs.setContent(&(outData[0]), outData.size());
			}
			if (impulseIn)
			{
				INT32 * data;
				UINT32 count;
				count = ini.getContent(data);

				//DOUBLE totalImpulse = 0;

				VINT32 outData;
				// for each impulse
				for (UINT32 i = 0; i < count; i+=3) {

					// extract impulses and sum
					INT32 index;
					DOUBLE value;
					getImpulse(data,i,index,value);

					// for each target of the source of that impulse
					for (UINT32 j = 0; j < spikeInds[index].size(); ++j) {
						// add output impulse to the list
						addImpulse(outData, spikeInds[index][j], value);
					}

				}

				outi.setContent(&(outData[0]), outData.size());
			}

			//	ok
			return C_OK;
		}

	}

	//	if we service the event, we return C_OK
	//	if we don't, we should return S_NULL to indicate that we didn't
	return S_NULL;
}
コード例 #4
0
Symbol COMPONENT_CLASS_CPP::event(Event* event)
{
    switch(event->type)
    {
    case EVENT_STATE_SET:
    {

        //	extract DataML
        EventStateSet* data = (EventStateSet*) event->data;
        XMLNode xmlNode(data->state);
        DataMLNode nodeState(&xmlNode);

        // obtain the parameters
        size = nodeState.getField("size").getINT32();
        numElementsOut = size;

        // Hard-code dataType initialization. I don't know if theres a
        // way to set this in the XML. It doesn't seem to get set when
        // SpineCreator writes out the experiment.xml file.
        dataType = ANALOG;

        portno = nodeState.getField("port").getINT32();

        // get the server name
        if (nodeState.hasField("host")) {
            server = nodeState.getField("host").getSTRING();
        } else {
            server = "localhost";
        }

        // get the connection name
        if (nodeState.hasField("name")) {
            conn_name = nodeState.getField("name").getSTRING();
        } else {
            conn_name = "unknown";
        }

        // how often to send an output
        if (nodeState.hasField("skip")) {
            skip = nodeState.getField("skip").getDOUBLE();
        } else {
            skip = 0.01;
        }

        /*string command = nodeState.getField("command").getSTRING();

        // launch the command if it is not blank
        if (!command.compare("")) {
        // use fork to run in new thread
        system(command.c_str());
        }*/


        // scale buffer
        buffer.resize(size,0);

        dt = 1000.0f * time->sampleRate.den / time->sampleRate.num;
        next_t = 0;

        return C_OK;
    }

    // CREATE THE PORTS
    case EVENT_INIT_CONNECT:
    {
        if (event->flags & F_FIRST_CALL)
        {
            switch (dataType) {
            case EVENT:
                outs.setName("out");
                outs.create(hComponent);
                outs.setCapacity(numElementsOut);
                break;
            case ANALOG:
                out.setName("out");
                out.create(hComponent);
                out.setStructure(TYPE_DOUBLE | TYPE_REAL, Dims(numElementsOut).cdims());
                break;
            case IMPULSE:
            {
                berr << "Not implemented";
                break;
            }
            default:
            {
                berr << "Unknown dataType: " << (int)dataType;
                break;
            }
            }
        }

        //	on last call
        if (event->flags & F_LAST_CALL)
        {

            // connect the socket:

            // start client
            if (!client.createClient(server, portno, size, dataType, RESP_AM_TARGET, conn_name)) {
                berr << client.getLastError();
            }

            /*client.connectClient(portno);

            // handshake
            client.handShake(RESP_AM_TARGET);

            // send data type
            bool ok;
            dataType = client.recvDataType(ok);

            // get size
            int confirmSize = client.recvSize(ok);
            if (size != confirmSize)
            berr << "Wrong size of data coming into External Source: " << double(confirmSize) << " should be: " << double(size);
            */
        }

        //	ok
        return C_OK;
    }

    case EVENT_RUN_SERVICE:
    {
        // current simulation time
        double t = float(time->now) * dt;

        //cout << "Input t = " << t << endl;

        // implement skipping
        if (t > next_t - dt + 0.00001) {
            next_t = t + skip;

            // only analog for now - will add spikes etc.. later

            switch (dataType) {
            case EVENT:
            {
                berr << "Not implemented";
                break;
            }
            case ANALOG:
                client.recvData((char *) &(buffer[0]), buffer.size()*sizeof(double));
                break;
            case IMPULSE:
            {
                berr << "Not implemented";
                break;
            }
            default:
            {
                berr << "Bad value for dataType in EVENT_RUN_SERVICE";
                break;
            }
            }

            
        }
        
        out.setContent(&(buffer[0]));

        //	ok
        return C_OK;
    }

    case EVENT_RUN_STOP:
    {

        //client.sendEnd();

        client.disconnectClient();

        //	ok
        return C_OK;
    }

    }

    //	if we service the event, we return C_OK
    //	if we don't, we should return S_NULL to indicate that we didn't
    return S_NULL;
}