COMMENT This repeatconn mechanism written by marianne.case@uci.edu on April 19, 2011. It decreases the time taken to decide which connections to make between cell by an order of magnitude, compared to Rob & Viji's code (even the version that I parallelized). How it works, in context with hoc: for each cell type (as postsynaptic cell type) - hoc > for each cell type (as presynaptic cell type) - hoc > > make a vector of gids of all cells owned by this processor of the postsynaptic type - hoc > > send vector, presynaptic cell type axonal distribution, number of connections desired to NMODL - hoc > > for each postsynaptic cell of postsynaptic cell type owned by this processor - NMODL > > > calculate the distance between every presynaptic cell of presynaptic cell type and this postsynaptic cell - NMODL > > > choose the desired number of connections at various distances - NMODL (as defined by the presynaptic axonal distribution and total # of desired connections) - NMODL > > > randomly pick the specific connections, up to the desired and/or available number for each distance - NMODL > > > for each desired connection, add the gid of the presynaptic cell to a vector - NMODL > > return the filled vector to hoc - NMODL > > make all the connections listed in the vector - hoc The way to call this from hoc: - first, install the vector method with this argument: install_repeatconn() - then, create a vector with the parameters for the connections (parameters described below) - then, create a vector with the gids of the post synaptic cells - and finally, create an empty placeholder vector with 3x the elements as the number of connections desired - finally, populate the placeholder vector with the connection information using the following command: conns2make.repeatconn(params, postcellgids) params vector has 26 elements: 0 - start gid of the presynaptic cell type 1 - end gid of the presynaptic cell type (assume continuous range) 2 - total number of connections desired from this presynaptic cell type to this postsynaptic cell type 3 - total number of cells of the postsynaptic type 4 - number of cells of postsynaptic type with gids owned by this host 5 - total distance over which distance distribution applies (um) 6 - resolution of the fit to the distribution, in # steps to take 7 - distribution equation coefficient a (for this presynaptic cell type) 8 - distribution equation coefficient b (for this presynaptic cell type) 9 - distribution equation coefficient c (for this presynaptic cell type) 10 - number of position bins along the X axis for presynaptic cell type 11 - number of position bins along the Y axis for presynaptic cell type 12 - number of position bins along the Z axis for presynaptic cell type 13 - length (um) of bins along the X axis for presynaptic cell type 14 - length (um) of bins along the Y axis for presynaptic cell type 15 - length (um) of bins along the Z axis for presynaptic cell type 16 - height in the Z direction, of the layer in which the presynaptic cell type exists 17 - number of position bins along the X axis for postsynaptic cell type 18 - number of position bins along the Y axis for postsynaptic cell type 19 - number of position bins along the Z axis for postsynaptic cell type 20 - length (um) of bins along the X axis for presynaptic cell type 21 - length (um) of bins along the Y axis for presynaptic cell type 22 - length (um) of bins along the Z axis for presynaptic cell type 23 - height in the Z direction, of the layer in which the postsynaptic cell type exists 24 - start gid of the postsynaptic cell type 25 - high index at which to start the random number stream (for each gid) should be set such that there are no overlaps per each gid, so err on the side of caution when setting the next high index. ENDCOMMENT VERBATIM # include # include # include ENDVERBATIM NEURON { SUFFIX nothing } VERBATIM #ifndef NRN_VERSION_GTEQ_8_2_0 #include extern uint32_t nrnRan4int(uint32_t* idx1, uint32_t idx2); extern double* vector_vec(); extern int vector_capacity(); extern void* vector_arg(); #endif //void srand(unsigned seed); ENDVERBATIM VERBATIM static double get_x_pos (int gid, int gmin, int BinNumX, int BinNumYZ, int binSizeX) { double pos; int CellNum, tmp; CellNum=gid - gmin+1; tmp = floor((CellNum-1)/BinNumYZ); pos = (tmp%BinNumX)*binSizeX+binSizeX/2.0; return pos; } static double get_y_pos (int gid, int gmin, int BinNumY, int BinNumZ, int binSizeY) { double pos; int CellNum, tmp; CellNum=gid - gmin+1; tmp = floor((CellNum-1)/BinNumZ); pos = (tmp%BinNumY)*binSizeY+binSizeY/2.0; return pos; } static double get_z_pos (int gid, int gmin, int BinNumZ, int binSizeZ, int ZHeight) { double pos; int CellNum; CellNum=gid - gmin+1; pos = ((CellNum-1)%BinNumZ)*binSizeZ+binSizeZ/2+ZHeight; return pos; } static double repeatconn (void* vv) { int repeatfinal, ny, nz, num_pre, num_post, gmin, gmax, maxd, steps, myflaggy, myi, postgmin, stepover; double *x, *y, *z, a, b, c, nconv, ncell; /* Get hoc vectors into c arrays */ repeatfinal = vector_instance_px(vv, &x); // x is an array corresponding // to the placeholder vector // of connections to make ny = vector_arg_px(1, &y); // y is an array of parameters nz = vector_arg_px(2, &z); // z is an array of the postsynaptic gids /* Load the parameters from the param array */ gmin = y[0]; // presynaptic start gid gmax = y[1]; // presynaptic end gid num_pre = gmax - gmin + 1; // number of presynaptic cells nconv = y[2]; // total number of desired connections ncell = y[3]; // total number of postsynaptic cells num_post = y[4]; // number of postsynaptic cells owned by this host maxd = y[5]; // total distance over which distribution fits steps = y[6]; // resolution of the distribution fit (in steps) a = y[7]; // distribution fit coefficient a b = y[8]; // distribution fit coefficient b c = y[9]; // distribution fit coefficient c postgmin = y[24]; // postsynaptic start gid stepover = y[26]; // buffer size for number of conns for results vector myi=2; // myi will give the next index into finalconn // 0 is reserved for # conns to make // 1 is reserved for the last high index used by nrnRan4int /* Get positions of the presynaptic and postsynaptic cells*/ double prepos [num_pre][3]; double postpos [num_post][3]; int cell; for (cell=0; celltu[maxi]) { maxi=step; } tsum = tsum + tu[step]; } if (tu[maxi]/tsum*nconv < 0.5) { //tsum) nconv=nconn*1.0/ncell for (step=0; step dln[step+1]) { if (szp [step+1] - dln[step+1]>rem) { extra = rem; } else { extra = szp [step+1] - dln[step+1]; } dln[step+1] = dln[step+1] + extra; dln[step] = dln[step] - extra; rem = rem - extra; } } if (rem>0 && step>0) { // if that still doesn't satisfy all the remainder if (szp [step-1] > dln[step-1]) { if (szp [step-1] - dln[step-1]>rem) { extra = rem; } else { extra = szp [step-1] - dln[step-1]; } dln[step-1] = dln[step-1] + extra; dln[step] = dln[step] - extra; rem = rem - extra; } } } } /*if (ncell==2 && num_pre==3) { for (step=0; step< steps; step++) { printf("step: %d szp: %d dln: %d\n", step, szp [step], dln[step]); } }*/ rem=0; for (step=0; step0 && szr>0) { // if this particular step wants any connections /* Find all the possible connections for each distance level */ /*if (ncell==2 && num_pre==3) { printf("precells=%d postcells=%d step=%d szr=%d\n", num_pre, ncell, step, szr); }*/ int r[szr]; // Define an array the length of the number of available unique pre-cells int rout[dln[step]]; // Define an array the length of the number of desired connections for (i=0; i< szr; i++) { r[i] = sortedpos [i] [step]; // Fill the array with the available unique pre-cells } /* this random routine allows a pre-cell to make multiple connections on the post cell and makes the total number of desired connections*/ u_int32_t randi; for (i=0; i10000) { // if (z[0]==21504) { //printf("step=%d, gid=%f, myi=%d\n", step, z[n], myi); //} //} } if (idx1>maxidx1) { maxidx1=idx1;} } x [0] = myi-2; // fill the first element of the array (vector) // with the total number of connections to make, // which may be less than the desired number (and // hence the size of the array) x [1] = (double)maxidx1; return repeatfinal; } ENDVERBATIM : This PROCEDURE install_repeatconn() should be called from hoc : to make the repeatconn procedure available there PROCEDURE install_repeatconn () { VERBATIM install_vector_method("repeatconn", repeatconn); ENDVERBATIM }