Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Database updates to pass array arguments #126

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 42 additions & 23 deletions src/cmd/src/DBMessenger.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#include <RAT/DBMessenger.hh>
#include <RAT/DB.hh>
#include <RAT/DBTextLoader.hh>

#include <G4UIdirectory.hh>
#include <G4StateManager.hh>

Expand All @@ -17,7 +16,7 @@ void DBMessenger::Init(DB *dbToUse)
// Build UI commands
G4UIdirectory* dbdir = new G4UIdirectory("/rat/db/");
dbdir->SetGuidance("RATDB commands");

// load database file command
loadCmd = new G4UIcmdWithAString("/rat/db/load", this);
loadCmd->SetParameterName("filename", false); // required
Expand All @@ -32,7 +31,7 @@ void DBMessenger::Init(DB *dbToUse)
setCmd->SetParameter(aParam);
aParam = new G4UIparameter("newvalue", 's', false); //required
setCmd->SetParameter(aParam);

// connect to server command
serverCmd = new G4UIcmdWithAString("/rat/db/server", this);
serverCmd->SetParameterName("server_url", false); // required
Expand Down Expand Up @@ -62,7 +61,7 @@ void DBMessenger::SetNewValue(G4UIcommand * command, G4String newValue)
{
G4ApplicationState state = G4StateManager::GetStateManager()->GetCurrentState();
if (state != G4State_PreInit)
Log::Die("Error: Cannot call " + command->GetCommandPath()
Log::Die("Error: Cannot call " + command->GetCommandPath()
+ " after /run/initialize.");

if (command == loadCmd) {
Expand All @@ -71,7 +70,7 @@ void DBMessenger::SetNewValue(G4UIcommand * command, G4String newValue)
istringstream args(newValue);
string tbl_descriptor, field, value;
args >> tbl_descriptor >> field >> value;

Set(tbl_descriptor, field, value);
} else if (command == serverCmd) {
Server(newValue);
Expand All @@ -91,37 +90,57 @@ void DBMessenger::Load(std::string filename)
db->Load(filename, true /*printPath*/);
}

void DBMessenger::Set(std::string tbl_descriptor, std::string field,
std::string val)
void DBMessenger::Set(std::string tbl_descriptor, std::string field, std::string val)
{
string table;
string index;

if (DB::ParseTableName(tbl_descriptor, table, index)) {
// Just need to figure out value now
Tokenizer t(val);
switch (t.Next()) {
case Tokenizer::TYPE_INTEGER: db->SetI(table, index, field, t.AsInt());
break;
case Tokenizer::TYPE_DOUBLE: db->SetD(table, index, field, t.AsDouble());
break;
case Tokenizer::TYPE_STRING: db->SetS(table, index, field, t.Token());
break;
default:
Log::Die("Error parsing value: " + val);
return;
json::Reader reader(val);
json::Value jval;
reader.getValue(jval); //will throw parser_error and abort if malformed

if (field[field.length()-1] == ']') {
size_t idx = atoi(field.substr(field.rfind("[")+1).c_str());
switch (jval.getType()) {
case json::TINTEGER:
case json::TUINTEGER:
case json::TREAL:
case json::TBOOL:
case json::TSTRING:
case json::TOBJECT:
case json::TARRAY:
DB::Get()->SetArrayIndex(table,index,field,idx,jval);
break;
case json::TNULL:
Log::Die("DB: Null value not supported in RATDB");
}
} else {
switch (jval.getType()) {
case json::TINTEGER:
case json::TUINTEGER:
case json::TREAL:
case json::TBOOL:
case json::TSTRING:
case json::TOBJECT:
case json::TARRAY:
DB::Get()->Set(table,index,field,jval);
break;
case json::TNULL:
Log::Die("DB: Null value not supported in RATDB");
}
}

info << "DB: Setting " << table << "[" << index << "]" << " " << field
<< " to " << t.Token() << newline;
} else
info << "DB: Setting " << table << "[" << index << "]" << " " << field << " to " << val << newline;
} else {
Log::Die("Malformed table name: " + tbl_descriptor);
}
}

void DBMessenger::Server(std::string url)
{
info << "RATDB: Connecting to CouchDB server at " << url << "\n";

db->SetServer(url);
}

Expand Down
4 changes: 2 additions & 2 deletions src/cmd/src/GLG4DebugMessenger.cc
Original file line number Diff line number Diff line change
Expand Up @@ -337,9 +337,9 @@ SetNewValue(G4UIcommand * command,G4String newValues)
int value = new_value != 0.0 ? 0 : 1; // invert meaning

if (parameterName == "omit_muon_processes") {
db->SetI("MC", "", "muon_processes", value);
db->Set("MC", "", "muon_processes", value);
} else if (parameterName == "omit_hadronic_processes") {
db->SetI("MC", "", "hadronic_processes", value);
db->Set("MC", "", "hadronic_processes", value);
} else {
RAT::Log::Die(dformat("/glg4debug/glg4param has been deprecated and '%s' is unsupported", parameterName.c_str()));
}
Expand Down
131 changes: 68 additions & 63 deletions src/db/include/RAT/DB.hh
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ DB *db = DB::Get();
DBLinkPtr lmedia = db->GetLink("MEDIA", "acrylic"); // Link to MEDIA[acrylic]
double rindex = lmedia->GetD("index_of_refraction");
@endcode
*
*
* You can hold onto DBLinkPtr objects as long as you like. If
* you expect you will need to access the same table at various
* points in your code, you can obtain a link pointer in your
Expand All @@ -88,31 +88,33 @@ double rindex = lmedia->GetD("index_of_refraction");
#include <set>
#include <deque>
#include <RAT/HTTPDownloader.hh>
#include <RAT/DBLink.hh>
#include <RAT/DBFieldCallback.hh>
#include <RAT/smart_ptr.hpp>
#include <RAT/Log.hh>
#include <RAT/DBTable.hh>

namespace RAT {


class DB; // Forward decl to allow for static DB member inside itself
class DBTable;
class DBLink;

class DBTableKey {
public:
DBTableKey() : name(""), index(""), run(0) {};
DBTableKey (const std::string &_name, const std::string &_index, const int _run=0)
: name(_name), index(_index), run(_run) {};

std::string name;
std::string index;
int run;

bool operator< (const DBTableKey &rhs) const {
return (name < rhs.name) || (name == rhs.name && index < rhs.index)
return (name < rhs.name) || (name == rhs.name && index < rhs.index)
|| (name == rhs.name && index == rhs.index && run < rhs.run);
};

bool operator== (const DBTableKey &rhs) const {
return (name == rhs.name) && (index == rhs.index) && (run == rhs.run);
};
Expand Down Expand Up @@ -145,12 +147,12 @@ public:
* @param[out] table Just the table name
* @param[out] index Just the index name. Empty string if no
* index.
*
*
* @returns True if @p descriptor was a properly formatted table name.
*/
static bool ParseTableName(std::string descriptor,
static bool ParseTableName(std::string descriptor,
std::string &table, std::string &index);

/** Reads a file and returns all the RATDB tables found inside.
* Works with both RATDB native and JSON files */
static std::vector<RAT::DBTable *> ReadRATDBFile(const std::string &filename);
Expand Down Expand Up @@ -181,12 +183,12 @@ public:
*/
int Load(std::string filename, bool printPath=false);

/** Put a DBTable into the database. Returns 1 if success and 0 if failure.
/** Put a DBTable into the database. Returns 1 if success and 0 if failure.
The DB class will take over responsibility for freeing the table memory
when needed. */
int LoadTable(DBTable *table);

/** Load DB text file of tables into memory.
/** Load DB text file of tables into memory.
*
* This function does not search in $GLG4DATA automatically, so it
* must be given a file name relative to the current directory or
Expand All @@ -204,7 +206,7 @@ public:

/** Load standard tables into memory.
*
* Currently, the standard tables are $GLG4DATA/ *.ratdb.
* Currently, the standard tables are $GLG4DATA/ *.ratdb.
*/
int LoadDefaults();

Expand All @@ -220,15 +222,15 @@ public:
/** Get the default run number used for new links **/
int GetDefaultRun() const;

/** Obtain a link to a particular table and index with default run.
/** Obtain a link to a particular table and index with default run.
*
* Note that even if your table does not have an index value,
* you should still use this method, but with an empty index.
* (The default value)
*/
DBLinkPtr GetLink(std::string tblname, std::string index="");

/** Obtain a link to a particular table and index with given run.
/** Obtain a link to a particular table and index with given run.
*
* If you have an empty index, pass "" as the index value.
*/
Expand All @@ -237,7 +239,7 @@ public:

/** Obtain a link to all tables with the same name, but different
* indexes.
*
*
* LinkGroups are useful if you want to step through all the
* instances of the same kind of table, like GEO.
*/
Expand All @@ -247,45 +249,18 @@ public:
// DO THIS AFTER loading files from disk, or your changes will be
// stomped on later.

/** Set integer field in user plane, no table index. */
void SetI(std::string tblname, std::string fieldname, int val)
{ SetI(tblname, "", fieldname, val); };

/** Set integer field in user plane, with table index. */
void SetI(std::string tblname, std::string index, std::string fieldname, int val);

/** Set double field in user plane, no table index. */
void SetD(std::string tblname, std::string fieldname, double val)
{ SetD(tblname, "", fieldname, val); };
/** Set double field in user plane, with table index. */
void SetD(std::string tblname, std::string index, std::string fieldname, double val);

/** Set string field in user plane, no table index. */
void SetS(std::string tblname, std::string fieldname, std::string val)
{ SetS(tblname, "", fieldname, val); };
/** Set string field in user plane, with table index. */
void SetS(std::string tblname, std::string index, std::string fieldname, std::string val);


/** Set integer array field in user plane, no table index. */
void SetIArray(std::string tblname, std::string fieldname, const std::vector<int> &val)
{ SetIArray(tblname, "", fieldname, val); };
/** Set integer array field in user plane, with table index. */
void SetIArray(std::string tblname, std::string index, std::string fieldname, const std::vector<int> &val);

/** Set double array field in user plane, no table index. */
void SetDArray(std::string tblname, std::string fieldname, const std::vector<double> &val)
{ SetDArray(tblname, "", fieldname, val); };
/** Set double array field in user plane, with table index. */
void SetDArray(std::string tblname, std::string index, std::string fieldname, const std::vector<double> &val);

/** Set string array field in user plane, no table index. */
void SetSArray(std::string tblname, std::string fieldname, const std::vector<std::string> &val)
{ SetSArray(tblname, "", fieldname, val); };
/** Set string array field in user plane, with table index. */
void SetSArray(std::string tblname, std::string index, std::string fieldname, const std::vector<std::string> &val);


/** Set field in user plane, no table index. */
template <typename T> void Set(const std::string &tblname, const std::string &fieldname, const T &val);

/** Set field in user plane, with table index. */
template <typename T> void Set(const std::string &tblname, const std::string &index, const std::string &fieldname, const T &val);

/** Set array field index in user plane, no table index. */
template <typename T> void SetArrayIndex(const std::string &tblname, const std::string &fieldname, size_t idx, const T &val);

/** Set array field index in user plane, with table index. */
template <typename T> void SetArrayIndex(const std::string &tblname, const std::string &index, const std::string &fieldname, size_t idx, const T &val);

/************************DBLink interface********************/
// This is the low level interface that DBLinks use.
// You should not call these methods.
Expand All @@ -299,7 +274,7 @@ public:
what you are doing! */
DBTable *GetRunTable(std::string tblname, std::string index, int runNumber)
{ return FindTable(tblname, index, runNumber); };

/** Get pointer to a table in default plane: do not use unless you know
what you are doing! */
DBTable *GetDefaultTable(std::string tblname, std::string index)
Expand All @@ -322,20 +297,20 @@ public:
* for debugging purposes.
*/
int NumLinks() { return links.size(); };

virtual std::vector<int> FetchIArray(const std::string &tableID, const std::string &fieldname);
virtual std::vector<double> FetchDArray(const std::string &tableID, const std::string &fieldname);

protected:
/** Obtain a pointer to a table loaded in memory.
/** Obtain a pointer to a table loaded in memory.
*
* @returns Pointer to table if found, otherwise 0.
*/
DBTable *FindTable(std::string tblname, std::string index, int runNumber);

/** Obtain a pointer to a table in memory, or create it if
* not found.
*
*
* @returns Pointer to existing table, or pointer to new table,
* which is also added to @p tblset.
*/
Expand All @@ -358,21 +333,21 @@ protected:
/** URL to CouchDB server. Empty string means no server will be
* used. */
std::string server;

/** Cache of table names present on the CouchDB server. Check this before issuing a query. */
std::set<std::string> tableNamesOnServer;

/** Cache of full table keys (name, index, run) that are *not* on the server.
Important to cut down on needless network traffic from future queries once
a rejection has been received. */
std::set<RAT::DBTableKey> tablesNotOnServer;

/** Helper class to download files over HTTP/HTTPS */
HTTPDownloader downloader;

/** Set of all tables. Run 0 signifies default and run -1 is user-override. */
DBTableSet tables;

/** FIFO of tables fetched from the server. Second element of pair is
indicates if the size from this key "is real". When the same table
is added for multiple runs, only the last run should be set to true. */
Expand All @@ -384,4 +359,34 @@ protected:

} // namespace RAT

// Unfortunately necessary to include this after definition of DB to avoid circular references
#include <RAT/DBLink.hh>

template <typename T> void RAT::DB::Set(const std::string &tblname, const std::string &fieldname, const T &val) {
Set(tblname, "", fieldname, val);
}

/** Set field in user plane, with table index. */
template <typename T> void RAT::DB::Set(const std::string &tblname, const std::string &index, const std::string &fieldname, const T &val) {
DBTable *t = FindOrCreateTable(tblname, index, -1);
t->Set(fieldname, val);
}

/** Set array field index in user plane, no table index. */
template <typename T> void RAT::DB::SetArrayIndex(const std::string &tblname, const std::string &fieldname, size_t idx, const T &val) {
SetArrayIndex(tblname, "", fieldname, idx, val);
}

/** Set array field index in user plane, with table index. */
template <typename T> void RAT::DB::SetArrayIndex(const std::string &tblname, const std::string &index, const std::string &fieldname, size_t idx, const T &val) {
DBTable *t = FindOrCreateTable(tblname, index, -1);
DBLinkPtr p = GetLink(tblname,index); //This ensures we always grab either the previously set or default plane array without keeping track explicitly
json::Value jval = p->Get<json::Value>(fieldname);
Log::Assert(jval.getType() == json::TARRAY,"RATDB: Cannot set an index for an item that is not an array!");
jval[index] = val;
t->Set(fieldname,jval);
}



#endif
Loading