Example #1
0
const Cinfo * HDF5DataWriter::initCinfo()
{
  static DestFinfo process(
      "process",
      "Handle process calls. Write data to file and clear all Table objects"
      " associated with this. Hence you want to keep it on a slow clock"
      " 1000 times or more slower than that for the tables.",
  		new ProcOpFunc<HDF5DataWriter>( &HDF5DataWriter::process)
	);
  static  DestFinfo reinit(
      "reinit",
      "Reinitialize the object. If the current file handle is valid, it tries"
      " to close that and open the file specified in current filename field.",
  		new ProcOpFunc<HDF5DataWriter>( &HDF5DataWriter::reinit )
    );
  static Finfo * processShared[] = {
    &process, &reinit
  };
  static SharedFinfo proc(
      "proc",
      "Shared message to receive process and reinit",
      processShared, sizeof( processShared ) / sizeof( Finfo* ));
  static Finfo * finfos[] = {
    requestOut(),
    clear(),
    recvDataBuf(),        
    &proc,
  };

  static string doc[] = {
    "Name", "HDF5DataWriter",
    "Author", "Subhasis Ray",
    "Description", "HDF5 file writer for saving data tables. It saves the tables connected"
    " to it via `requestOut` field into an HDF5 file.  The path of the"
    " table is maintained in the HDF5 file, with a HDF5 group for each"
    " element above the table."
    "\n"
    "Thus, if you have a table `/data/VmTable` in MOOSE, then it will be"
    " written as an HDF5 table called `VmTable` inside an HDF5 Group called"
    " `data`."
    "\n"
    "However Table inside Table is considered a pathological case and is"
    " not handled.\n"
    "At every process call it writes the contents of the tables to the file"
    " and clears the table vectors. You can explicitly force writing of the"
    " data via the `flush` function."
  };

	static Dinfo< HDF5DataWriter > dinfo;
    static Cinfo cinfo(
        "HDF5DataWriter",
        HDF5WriterBase::initCinfo(),
        finfos,
        sizeof(finfos)/sizeof(Finfo*),
		&dinfo,
	doc, sizeof( doc ) / sizeof( string ));
    return &cinfo;
}
Example #2
0
void HDF5DataWriter::reinit(const Eref & e, ProcPtr p)
{
    steps_ = 0;
    for (unsigned int ii = 0; ii < data_.size(); ++ii){
        H5Dclose(datasets_[ii]);
    }
    data_.clear();
    src_.clear();
    func_.clear();
    datasets_.clear();
    unsigned int numTgt = e.element()->getMsgTargetAndFunctions(e.dataIndex(),
                                                                requestOut(),
                                                                src_,
                                                                func_);
    assert(numTgt ==  src_.size());
    // TODO: what to do when reinit is called? Close the existing file
    // and open a new one in append mode? Or keep adding to the
    // current file?
    if (filename_.empty()){
        filename_ = "moose_data.h5";
    }
    if (filehandle_ > 0 ){
        close();
    }
    if (numTgt == 0){
        return;
    }
    openFile();
    for (unsigned int ii = 0; ii < src_.size(); ++ii){
        string varname = func_[ii];
        size_t found = varname.find("get");
        if (found == 0){
            varname = varname.substr(3);
            if (varname.length() == 0){
                varname = func_[ii];
            } else {
                // TODO: there is no way we can get back the original
                // field-name case. tolower will get the right name in
                // most cases as field names start with lower case by
                // convention in MOOSE.
                varname[0] = tolower(varname[0]);
            }
        }
        assert(varname.length() > 0);
        string path = src_[ii].path() + "/" + varname;
        hid_t dataset_id = getDataset(path);
        datasets_.push_back(dataset_id);
    }
    data_.resize(src_.size());
}
Example #3
0
/**
   Write data to datasets in HDF5 file. Clear all data in the table
   objects associated with this object. */
void HDF5DataWriter::process(const Eref & e, ProcPtr p)
{
    if (filehandle_ < 0){
        return;
    }
    // cout << "HDF5DataWriter::process: currentTime=" << p->currTime << endl;
    requestOut()->send(e, recvDataBuf()->getFid());
    for (map<string, vector < double > >:: iterator data_it = datamap_.begin(); data_it != datamap_.end(); ++data_it){        
        string path = data_it->first;
        // if (data_it->second.size() >= flushLimit_){
        map < string, hid_t >::iterator node_it = nodemap_.find(path);
        assert (node_it != nodemap_.end());
        if (node_it->second < 0){
            nodemap_[path] = get_dataset(path);
        }
        herr_t status = appendToDataset(nodemap_[path], data_it->second);
        if (status < 0){
            cerr << "Warning: appending data for object " << data_it->first << " returned status " << status << endl;                
        }
        data_it->second.clear();
    }    
}
Example #4
0
/**
 * @brief Reinitialize
 *
 * @param e
 * @param p
 */
void Table::reinit( const Eref& e, ProcPtr p )
{
    tablePath_ = e.id().path();
    unsigned int numTick = e.element()->getTick();
    Clock* clk = reinterpret_cast<Clock*>(Id(1).eref().data());
    dt_ = clk->getTickDt( numTick );

    /** Create the default filepath for this table.  */
    if( useStreamer_ )
    {
        // The first column is variable time.
        columns_.push_back( "time" );
        // And the second column name is the name of the table.
        columns_.push_back( moose::moosePathToUserPath( tablePath_ ) );

        // If user has not set the filepath, then use the table path prefixed
        // with rootdit as path.
        if( ! outfileIsSet_ )
            setOutfile( rootdir_ +
                    moose::moosePathToUserPath(tablePath_) + '.' + format_ 
                    );
    }

    input_ = 0.0;
    vec().resize( 0 );
    lastTime_ = 0;
    vector< double > ret;
    requestOut()->send( e, &ret );
    vec().insert( vec().end(), ret.begin(), ret.end() );

    if( useStreamer_ )
    {
        zipWithTime( vec(), data_, lastTime_ );
        StreamerBase::writeToOutFile( outfile_, format_, "w", data_, columns_);
        clearVec();
        data_.clear();
        clearVec();
    }
}
Example #5
0
/**
   Write data to datasets in HDF5 file. Clear all data in the table
   objects associated with this object. */
void HDF5DataWriter::process(const Eref & e, ProcPtr p)
{
    if (filehandle_ < 0){
        return;
    }

    vector <double> dataBuf;
        requestOut()->send(e, &dataBuf);
    for (unsigned int ii = 0; ii < dataBuf.size(); ++ii){
        data_[ii].push_back(dataBuf[ii]);
    }
    ++steps_;
    if (steps_ >= flushLimit_){
        steps_ = 0;
        for (unsigned int ii = 0; ii < datasets_.size(); ++ii){
            herr_t status = appendToDataset(datasets_[ii], data_[ii]);
            data_[ii].clear();
            if (status < 0){
                cerr << "Warning: appending data for object " << src_[ii]
                     << " returned status " << status << endl;
            }
        }
    }
}
Example #6
0
void Function::process(const Eref &e, ProcPtr p)
{
    if (!_valid){
        return;
    }
    vector < double > databuf;
    requestOut()->send(e, &databuf);
    for (unsigned int ii = 0;
         (ii < databuf.size()) && (ii < _pullbuf.size());
         ++ii){
        *_pullbuf[ii] = databuf[ii];        
    }
    _value = getValue();
    _rate = (_value - _lastValue) / p->dt;
    switch (_mode){
        case 1: {
            valueOut()->send(e, _value);
            break;
        }
        case 2: {
            derivativeOut()->send(e, getDerivative());
            break;
        }
        case 3: {
            rateOut()->send(e, _rate);
            break;
        }
        default: {
            valueOut()->send(e, _value);
            derivativeOut()->send(e, getDerivative());
            rateOut()->send(e, _rate);
            break;
        }
    }
    _lastValue = _value;
}
Example #7
0
void Table::process( const Eref& e, ProcPtr p )
{
    lastTime_ = p->currTime;

    // Copy incoming data to ret and insert into vector.
    vector< double > ret;
    requestOut()->send( e, &ret );
    vec().insert( vec().end(), ret.begin(), ret.end() );

    /*  If we are streaming to a file, let's write to a file. And clean the
     *  vector.  
     *  Write at every 5 seconds or whenever size of vector is more than 10k.
     */
    if( useStreamer_ )
    {
        if( fmod(lastTime_, 5.0) == 0.0 or getVecSize() >= 10000 )
        {
            zipWithTime( vec(), data_, lastTime_ );
            StreamerBase::writeToOutFile( outfile_, format_ , "a", data_, columns_ );
            data_.clear();
            clearVec();
        }
    }
}
Example #8
0
const Cinfo * HDF5DataWriter::initCinfo()
{
    static DestFinfo process(
        "process",
        "Handle process calls. Gets data from connected fields into a local"
        " buffer and dumps them to `filename` if the buffer length exceeds"
        " `flushLimit`",
        new ProcOpFunc<HDF5DataWriter>( &HDF5DataWriter::process)
                             );
    static  DestFinfo reinit(
        "reinit",
        "Reinitialize the object. If the current file handle is valid, it tries"
        " to close that and open the file specified in current filename field.",
        new ProcOpFunc<HDF5DataWriter>( &HDF5DataWriter::reinit )
                             );
    static Finfo * processShared[] = {
        &process, &reinit
    };

    static SharedFinfo proc(
        "proc",
        "Shared message to receive process and reinit",
        processShared, sizeof( processShared ) / sizeof( Finfo* ));

    static ValueFinfo< HDF5DataWriter, unsigned int> flushLimit(
      "flushLimit",
      "Buffer size limit for flushing the data from memory to file. Default"
      " is 4M doubles.",
      &HDF5DataWriter::setFlushLimit,
      &HDF5DataWriter::getFlushLimit);

    static Finfo * finfos[] = {
        requestOut(),
        &flushLimit,
        &proc,
    };



    static string doc[] = {
        "Name", "HDF5DataWriter",
        "Author", "Subhasis Ray",
        "Description", "HDF5 file writer for saving field values from multiple objects."
        "\n"
        "\nConnect the `requestOut` field of this object to the"
        " `get{Fieldname}` of other objects where `fieldname` is the"
        " target value field of type double. The HDF5DataWriter collects the"
        " current values of the fields in all the targets at each time step in"
        " a local buffer. When the buffer size exceeds `flushLimit` (default"
        " 4M), it will write the data into the HDF5 file specified in its"
        " `filename` field (default moose_output.h5). You can explicitly force"
        " writing by calling the `flush` function."
        "\n"
        "The dataset location in the output file replicates the MOOSE element"
        " tree structure. Thus, if you record the Vm field from"
        " `/model[0]/neuron[0]/soma[0], the dataset path will be"
        " `/model[0]/neuron[0]/soma[0]/vm`"
        "\n"
        "\n"
        "NOTE: The output file remains open until this object is destroyed, or"
        " `close()` is called explicitly."
    };

    static Dinfo< HDF5DataWriter > dinfo;
    static Cinfo cinfo(
        "HDF5DataWriter",
        HDF5WriterBase::initCinfo(),
        finfos,
        sizeof(finfos)/sizeof(Finfo*),
        &dinfo,
	doc, sizeof( doc ) / sizeof( string ));
    return &cinfo;
}
Example #9
0
const Cinfo * Function::initCinfo()
{
    ////////////////////////////////////////////////////////////
    // Value fields    
    ////////////////////////////////////////////////////////////
    static  ReadOnlyValueFinfo< Function, double > value(
        "value",
        "Result of the function evaluation with current variable values.",
        &Function::getValue);
    static ReadOnlyValueFinfo< Function, double > derivative(
        "derivative",
        "Derivative of the function at given variable values. This is calulated"
        " using 5-point stencil "
        " <http://en.wikipedia.org/wiki/Five-point_stencil> at current value of"
        " independent variable. Note that unlike hand-calculated derivatives,"
        " numerical derivatives are not exact.",
        &Function::getDerivative);
    static ReadOnlyValueFinfo< Function, double > rate(
        "rate",
        "Derivative of the function at given variable values. This is computed"
        " as the difference of the current and previous value of the function"
        " divided by the time step.",
        &Function::getRate);
    static ValueFinfo< Function, unsigned int > mode(
        "mode",
        "Mode of operation: \n"
        " 1: only the function value will be sent out.\n"
        " 2: only the derivative with respect to the independent variable will be sent out.\n"
        " 3: only rate (time derivative) will be sent out.\n"
        " anything else: all three, value, derivative and rate will be sent out.\n",
        &Function::setMode,
        &Function::getMode);
    static ElementValueFinfo< Function, string > expr(
        "expr",
        "Mathematical expression defining the function. The underlying parser\n"
        "is muParser. Hence the available functions and operators are (from\n"
        "muParser docs):\n"
        "\nFunctions\n"
        "Name        args    explanation\n"
        "sin         1       sine function\n"
        "cos         1       cosine function\n"
        "tan         1       tangens function\n"
        "asin        1       arcus sine function\n"
        "acos        1       arcus cosine function\n"
        "atan        1       arcus tangens function\n"
        "sinh        1       hyperbolic sine function\n"
        "cosh        1       hyperbolic cosine\n"
        "tanh        1       hyperbolic tangens function\n"
        "asinh       1       hyperbolic arcus sine function\n"
        "acosh       1       hyperbolic arcus tangens function\n"
        "atanh       1       hyperbolic arcur tangens function\n"
        "log2        1       logarithm to the base 2\n"
        "log10       1       logarithm to the base 10\n"
        "log         1       logarithm to the base 10\n"
        "ln  1       logarithm to base e (2.71828...)\n"
        "exp         1       e raised to the power of x\n"
        "sqrt        1       square root of a value\n"
        "sign        1       sign function -1 if x<0; 1 if x>0\n"
        "rint        1       round to nearest integer\n"
        "abs         1       absolute value\n"
        "min         var.    min of all arguments\n"
        "max         var.    max of all arguments\n"
        "sum         var.    sum of all arguments\n"
        "avg         var.    mean value of all arguments\n"
        "\nOperators\n"
        "Op  meaning         prioroty\n"
        "=   assignement     -1\n"
        "&&  logical and     1\n"
        "||  logical or      2\n"
        "<=  less or equal   4\n"
        ">=  greater or equal        4\n"
        "!=  not equal       4\n"
        "==  equal   4\n"
        ">   greater than    4\n"
        "<   less than       4\n"
        "+   addition        5\n"
        "-   subtraction     5\n"
        "*   multiplication  6\n"
        "/   division        6\n"
        "^   raise x to the power of y       7\n"
        "\n"
        "?:  if then else operator   C++ style syntax\n",
        &Function::setExpr,
        &Function::getExpr);

    static ValueFinfo< Function, unsigned int > numVars(
        "numVars",
        "Number of variables used by Function.",
        &Function::setNumVar,
        &Function::getNumVar);
    
    static FieldElementFinfo< Function, Variable > inputs(
        "x",
        "Input variables to the function. These can be passed via messages.",
        Variable::initCinfo(),
        &Function::getVar,
        &Function::setNumVar,
        &Function::getNumVar);

    static LookupValueFinfo < Function, string, double > constants(
        "c",
        "Constants used in the function. These must be assigned before"
        " specifying the function expression.",
        &Function::setConst,
        &Function::getConst);
    
    static ReadOnlyValueFinfo< Function, vector < double > > y(
        "y",
        "Variable values received from target fields by requestOut",
        &Function::getY);

    static ValueFinfo< Function, string > independent(
        "independent",
        "Index of independent variable. Differentiation is done based on this. Defaults"
        " to the first assigned variable.",
        &Function::setIndependent,
        &Function::getIndependent);

    ///////////////////////////////////////////////////////////////////
    // Shared messages
    ///////////////////////////////////////////////////////////////////
    static DestFinfo process( "process",
                              "Handles process call, updates internal time stamp.",
                              new ProcOpFunc< Function >( &Function::process ) );
    static DestFinfo reinit( "reinit",
                             "Handles reinit call.",
                             new ProcOpFunc< Function >( &Function::reinit ) );
    static Finfo* processShared[] =
            {
		&process, &reinit
            };
    
    static SharedFinfo proc( "proc",
                             "This is a shared message to receive Process messages "
                             "from the scheduler objects."
                             "The first entry in the shared msg is a MsgDest "
                             "for the Process operation. It has a single argument, "
                             "ProcInfo, which holds lots of information about current "
                             "time, thread, dt and so on. The second entry is a MsgDest "
                             "for the Reinit operation. It also uses ProcInfo. ",
                             processShared, sizeof( processShared ) / sizeof( Finfo* )
                             );

    static Finfo *functionFinfos[] =
            {
                &value,
                &rate,
                &derivative,
                &mode,
                &expr,
                &numVars,
                &inputs,
                &constants,
                &independent,
                &proc,
                requestOut(),
                valueOut(),
                rateOut(),
                derivativeOut(),
            };
    
    static string doc[] =
            {
                "Name", "Function",
                "Author", "Subhasis Ray",
                "Description",
                "General purpose function calculator using real numbers.\n"
                "It can parse mathematical expression defining a function and evaluate"
                " it and/or its derivative for specified variable values."
                "You can assign expressions of the form::\n"
                "\n"
                "f(c0, c1, ..., cM, x0, x1, ..., xN, y0,..., yP ) \n"
                "\n"
                " where `ci`'s are constants and `xi`'s and `yi`'s are variables."

                "The constants must be defined before setting the expression and"
                " variables are connected via messages. The constants can have any"
                " name, but the variable names must be of the form x{i} or y{i}"
                "  where i is increasing integer starting from 0.\n"
                " The variables can be input from other moose objects."
                " Such variables must be named `x{i}` in the expression and the source"
                " field is connected to Function.x[i]'s `input` destination field.\n"
                " In case the input variable is not available as a source field, but is"
                " a value field, then the value can be requested by connecting the"
                " `requestOut` message to the `get{Field}` destination on the target"
                " object. Such variables must be specified in the expression as y{i}"
                " and connecting the messages should happen in the same order as the"
                " y indices.\n"
                " This class handles only real numbers (C-double). Predefined constants"
                " are: pi=3.141592..., e=2.718281..."
            };
    
    static Dinfo< Function > dinfo;
    static Cinfo functionCinfo("Function",
                               Neutral::initCinfo(),
                               functionFinfos,
                               sizeof(functionFinfos) / sizeof(Finfo*),
                               &dinfo,
                               doc,
                               sizeof(doc)/sizeof(string));
    return &functionCinfo;
                                                    
}
Example #10
0
const Cinfo* Table::initCinfo()
{
    //////////////////////////////////////////////////////////////
    // Field Definitions
    //////////////////////////////////////////////////////////////
    static ValueFinfo< Table, double > threshold(
        "threshold"
        , "threshold used when Table acts as a buffer for spikes"
        , &Table::setThreshold
        , &Table::getThreshold
    );

    static ValueFinfo< Table, bool > useStreamer(
        "useStreamer"
        , "When set to true, write to a file instead writing in memory."
        " If `outfile` is not set, streamer writes to default path."
        , &Table::setUseStreamer
        , &Table::getUseStreamer
    );

    static ValueFinfo< Table, string > outfile(
        "outfile"
        , "Set the name of file to which data is written to. If set, "
        " streaming support is automatically enabled."
        , &Table::setOutfile
        , &Table::getOutfile
    );

    static ValueFinfo< Table, string > format(
        "format"
        , "Data format for table: default csv"
        , &Table::setFormat
        , &Table::getFormat
    );

    //////////////////////////////////////////////////////////////
    // MsgDest Definitions
    //////////////////////////////////////////////////////////////

    static DestFinfo spike(
        "spike",
        "Fills spike timings into the Table. Signal has to exceed thresh",
        new OpFunc1< Table, double >( &Table::spike )
    );

    static DestFinfo process(
        "process",
        "Handles process call, updates internal time stamp.",
        new ProcOpFunc< Table >( &Table::process )
    );

    static DestFinfo reinit(
        "reinit",
        "Handles reinit call.",
        new ProcOpFunc< Table >( &Table::reinit )
    );

    //////////////////////////////////////////////////////////////
    // SharedMsg Definitions
    //////////////////////////////////////////////////////////////
    static Finfo* procShared[] =
    {
        &process, &reinit
    };

    static SharedFinfo proc(
        "proc"
        , "Shared message for process and reinit"
        , procShared, sizeof( procShared ) / sizeof( const Finfo* )
    );

    //////////////////////////////////////////////////////////////
    // Field Element for the vector data
    // Use a limit of 2^20 entries for the tables, about 1 million.
    //////////////////////////////////////////////////////////////

    static Finfo* tableFinfos[] =
    {
        &threshold,		// Value
        &format,                // Value
        &outfile,               // Value 
        &useStreamer,           // Value
        handleInput(),		// DestFinfo
        &spike,			// DestFinfo
        requestOut(),		// SrcFinfo
        &proc,			// SharedFinfo
    };

    static string doc[] =
    {
        "Name", "Table",
        "Author", "Upi Bhalla",
        "Description",
        "Table for accumulating data values, or spike timings. "
        "Can either receive incoming doubles, or can explicitly "
        "request values from fields provided they are doubles. "
        "The latter mode of use is preferable if you wish to have "
        "independent control of how often you sample from the output "
        "variable. \n"
        "Typically used for storing simulation output into memory, or to file"
        " when stream is set to True \n"
        "There are two functionally identical variants of the Table "
        "class: Table and Table2. Their only difference is that the "
        "default scheduling of the Table (Clock Tick 8, dt = 0.1 ms ) "
        "makes it suitable for "
        "tracking electrical compartmental models of neurons and "
        "networks. \n"
        "Table2 (Clock Tick 18, dt = 1.0 s) is good for tracking "
        "biochemical signaling pathway outputs. \n"
        "These are just the default values and Tables can be assigned"
        " to any Clock Tick and timestep in the usual manner.",
    };

    static Dinfo< Table > dinfo;

    static Cinfo tableCinfo (
        "Table",
        TableBase::initCinfo(),
        tableFinfos,
        sizeof( tableFinfos ) / sizeof ( Finfo* ),
        &dinfo,
        doc,
        sizeof( doc ) / sizeof( string )
    );

    static string doc2[] =
    {
        doc[0], "Table2", doc[2], doc[3], doc[4], doc[5]
    };

    doc2[1] = "Table2";

    static Cinfo table2Cinfo (
        "Table2",
        TableBase::initCinfo(),
        tableFinfos,
        sizeof( tableFinfos ) / sizeof ( Finfo* ),
        &dinfo,
        doc2,
        sizeof( doc2 ) / sizeof( string )
    );

    return &tableCinfo;
}