diff --git a/src/cmd/src/DBMessenger.cc b/src/cmd/src/DBMessenger.cc index 6f396ed5..9f31acc6 100644 --- a/src/cmd/src/DBMessenger.cc +++ b/src/cmd/src/DBMessenger.cc @@ -2,7 +2,6 @@ #include #include #include - #include #include @@ -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 @@ -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 @@ -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) { @@ -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); @@ -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); } diff --git a/src/cmd/src/GLG4DebugMessenger.cc b/src/cmd/src/GLG4DebugMessenger.cc index ec7e7e3b..bc53c798 100644 --- a/src/cmd/src/GLG4DebugMessenger.cc +++ b/src/cmd/src/GLG4DebugMessenger.cc @@ -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())); } diff --git a/src/db/include/RAT/DB.hh b/src/db/include/RAT/DB.hh index aceef54a..8f537424 100644 --- a/src/db/include/RAT/DB.hh +++ b/src/db/include/RAT/DB.hh @@ -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 @@ -88,31 +88,33 @@ double rindex = lmedia->GetD("index_of_refraction"); #include #include #include -#include #include #include +#include +#include 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); }; @@ -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 ReadRATDBFile(const std::string &filename); @@ -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 @@ -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(); @@ -220,7 +222,7 @@ 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. @@ -228,7 +230,7 @@ public: */ 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. */ @@ -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. */ @@ -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 &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 &val); - - /** Set double array field in user plane, no table index. */ - void SetDArray(std::string tblname, std::string fieldname, const std::vector &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 &val); - - /** Set string array field in user plane, no table index. */ - void SetSArray(std::string tblname, std::string fieldname, const std::vector &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 &val); - - + /** Set field in user plane, no table index. */ + template void Set(const std::string &tblname, const std::string &fieldname, const T &val); + + /** Set field in user plane, with table index. */ + template 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 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 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. @@ -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) @@ -322,12 +297,12 @@ public: * for debugging purposes. */ int NumLinks() { return links.size(); }; - + virtual std::vector FetchIArray(const std::string &tableID, const std::string &fieldname); virtual std::vector 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. */ @@ -335,7 +310,7 @@ protected: /** 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. */ @@ -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 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 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. */ @@ -384,4 +359,34 @@ protected: } // namespace RAT +// Unfortunately necessary to include this after definition of DB to avoid circular references +#include + + template 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 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 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 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(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 diff --git a/src/db/include/RAT/DBLink.hh b/src/db/include/RAT/DBLink.hh index 2483bc66..bf67dec9 100644 --- a/src/db/include/RAT/DBLink.hh +++ b/src/db/include/RAT/DBLink.hh @@ -39,6 +39,7 @@ #include #include +#include #include namespace RAT { @@ -46,7 +47,6 @@ namespace RAT { class DB; - class DBLink { public: @@ -97,6 +97,13 @@ public: */ std::string GetS(const std::string &name); + /** Retrieve bool field. + * + * @throws DBNotFoundException if string field @p name does not + * exist. + */ + bool GetZ(const std::string &name); + /** Retrieve integer array field. * * @throws DBNotFoundException if integer array field @p name @@ -127,31 +134,34 @@ public: */ std::vector GetSArray(const std::string &name); + /** Retrieve bool array field. + * + * @throws DBNotFoundException if string array field @p name + * does not exist. + */ + std::vector GetZArray(const std::string &name); + /** Retrieve raw JSON value. * * @throws DBNotFoundException if field @p name * does not exist. */ json::Value GetJSON(const std::string &name); - - - // Used by DB class, do not use this yourself - void Unlink() { db = 0; }; - -protected: + /** Get the value of a field from the table, including plane * precedence rules. * - * This method is implemented as a template method to save having - * to write 8 Pick methods. - * * @param T C++ data type for field * @param fieldname Name of field - * @param ftype DB type for field */ - template - T Pick(std::string fieldname, DBTable::FieldType ftype) const; + template T Get(const std::string &fieldname); + + // Used by DB class, do not use this yourself + void Unlink() { db = 0; }; + +protected: + /** Pointer to DB which created this link. */ DB *db; @@ -166,6 +176,34 @@ protected: int currentRun; }; + template T DBLink::Get(const std::string &fieldname) { + + DBTable *tbl; + // First try user plane + tbl = db->GetUserTable(tblname, index); + if (!tbl || tbl->GetFieldType(fieldname) == DBTable::NOTFOUND) { + // Then try the run plane + tbl = db->GetRunTable(tblname, index, currentRun); + if (tbl) { + if (tbl->GetFieldType(fieldname) == DBTable::NOTFOUND) throw DBNotFoundError(tblname, index, fieldname); + } else { + // Finally try default plane + tbl = db->GetDefaultTable(tblname, index); + if (!tbl || tbl->GetFieldType(fieldname) == DBTable::NOTFOUND) { + throw DBNotFoundError(tblname, index, fieldname); + } + } + } + + // Make class explicit to satisfy Sun CC 5.3 + T value = tbl->DBTable::Get(fieldname); + + // Trace DB accesses + Log::TraceDBAccess(tblname, index, fieldname, value); + + return value; + } + } // namespace RAT diff --git a/src/db/include/RAT/DBTable.hh b/src/db/include/RAT/DBTable.hh index f766f8e8..5967b3c6 100644 --- a/src/db/include/RAT/DBTable.hh +++ b/src/db/include/RAT/DBTable.hh @@ -24,7 +24,7 @@ public: /** Create new empty table. */ DBTable(); - + /** Create new table from json object. */ DBTable(json::Value &jsonDoc); @@ -56,7 +56,7 @@ public: bool IsValidRun(const int run) { return (run >= run_begin) && (run <= run_end); }; /** Set run range for which this table is valid. Begin and end are inclusive*/ - void SetRunRange(int _run_begin, int _run_end) { + void SetRunRange(int _run_begin, int _run_end) { run_begin = _run_begin; run_end = _run_end; } /** Set this as a user-override table */ @@ -68,19 +68,19 @@ public: /** Data type of field. */ enum FieldType { NOTFOUND, /**< Type for fields that don't exist */ - INTEGER, DOUBLE, STRING, - INTEGER_ARRAY, DOUBLE_ARRAY, STRING_ARRAY, + INTEGER, DOUBLE, BOOLEAN, STRING, + INTEGER_ARRAY, DOUBLE_ARRAY, BOOLEAN_ARRAY, STRING_ARRAY, JSON }; - + /** Get data type of field in this table. * @returns DBTable::NOTFOUND if the field does not exist, otherwise * returns field type. */ FieldType GetFieldType(std::string name) const; - + /** Get a vector of field names. Call GetFieldType() to determine the type of each.*/ std::vector GetFieldList() const; - + /** Get value of integer field. * * @warning Due to the hash table implementation used here, this @@ -108,6 +108,16 @@ public: */ std::string GetS(const std::string &name) const; + /** Get value of bool field. + * + * @warning Due to the hash table implementation used here, this + * method raises an assertion error if @p name is not a valid field. + * Always use GetFieldType() to check if field exists if you are + * not sure! + */ + bool GetZ(const std::string &name) const; + + /** Get value of integer array field. * * @warning Due to the hash table implementation used here, this @@ -135,9 +145,18 @@ public: */ std::vector GetSArray(const std::string &name) const; + /** Get value of bool array field. + * + * @warning Due to the hash table implementation used here, this + * method raises an assertion error if @p name is not a valid field. + * Always use GetFieldType() to check if field exists if you are + * not sure! + */ + std::vector GetZArray(const std::string &name) const; + /** Get a JSON value for any field. - + This returns a json::Value for any field. This includes arbitrary JSON values that cannot be parsed by RATDB into standard C++ types. @@ -149,103 +168,29 @@ public: * Provided as a convenience to the DBLink implementation. Fetches * field based on type of @p T. */ - template inline T Get(const std::string &name) const; - - /** Create integer field if does not already exist, and set value. */ - inline void SetI(std::string name, int val) { - if (GetFieldType(name) == NOTFOUND) - bytes += 4; - table[name] = json::Value(val); - }; - - /** Create double field if does not already exist, and set value. */ - inline void SetD(std::string name, double val) { - if (GetFieldType(name) == NOTFOUND) - bytes += 8; - table[name] = json::Value(val); - }; - - /** Create string field if does not already exist, and set value. */ - inline void SetS(std::string name, std::string val) { - if (GetFieldType(name) == STRING) - bytes -= GetS(name).size(); - bytes += val.size(); - table[name] = json::Value(val); - }; - - /** Create integer array field if does not already exist, and set value. - * The array is copied into new storage. - */ - inline void SetIArray(std::string name, const std::vector &val) { - if (GetFieldType(name) != NOTFOUND) - bytes -= 4 * GetIArray(name).size(); - bytes += 4 * val.size(); - - json::Value tmpArray(val); - table[name] = tmpArray; - arrayTypeCache[name] = INTEGER_ARRAY; - }; + template inline T Get(const std::string &name) const; + + /** Set any type that is convertable to a json::Value */ + template inline void Set(const std::string &name, const T &value) { + table[name] = value; + } /** Set a deferred integer array field that will be fetched on demand */ void SetIArrayDeferred(std::string name, DBFieldCallback *callback) { iatbl_deferred[name] = callback; }; - /** Create double array field if does not already exist, and set value. - * The array is copied into new storage. - */ - inline void SetDArray(std::string name, const std::vector &val) { - if (GetFieldType(name) != NOTFOUND) - bytes -= 8 * GetIArray(name).size(); - bytes += 8 * val.size(); - - json::Value tmpArray(val); - table[name] = tmpArray; - arrayTypeCache[name] = DOUBLE_ARRAY; - }; - /** Set a deferred double array field that will be fetched on demand */ void SetDArrayDeferred(std::string name, DBFieldCallback *callback) { datbl_deferred[name] = callback; }; - /** Create string array field if does not already exist, and set value. - * The array is copied into new storage. - */ - inline void SetSArray(std::string name, const std::vector &val) { - if (GetFieldType(name) == STRING_ARRAY) { - std::vector sarray = GetSArray(name); - for (unsigned i=0; i < sarray.size(); i++) - bytes -= sarray[i].size(); - } - - for (unsigned i=0; i < val.size(); i++) - bytes += val[i].size(); - - json::Value tmpArray(val); - table[name] = tmpArray; - arrayTypeCache[name] = STRING_ARRAY; - }; - - /** Add a raw JSON value to the database. Homogeneous arrays should be - added using one of the SetIArray/SetDArray/SetSArray methods or they - will not be fetchable via GetIArray/GetDArray/GetSArray later. */ - inline void SetJSON(const std::string &name, const json::Value &value) { - // For now JSON values are exempt from size accounting - table[name] = value; - } - - /** Approximate number of bytes used by this table. Not very accurate, but should be - roughly proportional. */ - int GetBytes() const { return bytes; }; - protected: std::string tblname; /**< Name of table */ std::string index; /**< Index of table */ int run_begin; /**< First run in which this table is valid */ int run_end; /**< Last run in which this table is valid */ - int bytes; /**< Number of bytes required by values. Approximate */ - + /** JSON object storage of all fields, except callbacks */ json::Value table; @@ -254,16 +199,16 @@ protected: /** Hashtable storage of callbacks for deferred integer array fields. */ stlplus::hash< std::string, RAT::DBFieldCallback*, pyhash> iatbl_deferred; - + /** Hashtable storage of callbacks for deferred integer array fields. */ stlplus::hash< std::string, RAT::DBFieldCallback*, pyhash> datbl_deferred; - + }; /* Specialization of the above Get<> template */ template <> inline int DBTable::Get(const std::string &name) const -{ +{ return GetI(name); } @@ -279,6 +224,12 @@ inline std::string DBTable::Get(const std::string &name) const return GetS(name); } +template <> +inline bool RAT::DBTable::Get(const std::string &name) const +{ + return GetZ(name); +} + template <> inline std::vector RAT::DBTable::Get >(const std::string &name) const @@ -297,14 +248,21 @@ template <> inline std::vector RAT::DBTable::Get >(const std::string &name) const { - return GetSArray(name); + return GetSArray(name); +} + +template <> +inline std::vector +RAT::DBTable::Get >(const std::string &name) const +{ + return GetZArray(name); } template <> inline json::Value RAT::DBTable::Get(const std::string &name) const { - return GetJSON(name); + return GetJSON(name); } /** Exception: Field not found in RATDB */ @@ -316,7 +274,7 @@ public: * @param _index Index of table in which field could not be found * @param _field Name of field which could not be found */ - DBNotFoundError (const std::string &_table, const std::string &_index, + DBNotFoundError (const std::string &_table, const std::string &_index, const std::string &_field) : table(_table), index(_index), field(_field) { }; @@ -346,7 +304,7 @@ public: DBWrongTypeError(const std::string &_table, const std::string &_index, const std::string &_field, RAT::DBTable::FieldType _requestedType, RAT::DBTable::FieldType _actualType) - : DBNotFoundError(_table, _index, _field), + : DBNotFoundError(_table, _index, _field), requestedType(_requestedType), actualType(_actualType) { }; @@ -356,7 +314,7 @@ public: return table == other.table && index == other.index && field == other.field && requestedType == other.requestedType && actualType == other.actualType; } - + RAT::DBTable::FieldType requestedType; RAT::DBTable::FieldType actualType; }; diff --git a/src/db/include/RAT/json.hh b/src/db/include/RAT/json.hh index 93c0d68f..60d939ec 100644 --- a/src/db/include/RAT/json.hh +++ b/src/db/include/RAT/json.hh @@ -25,20 +25,20 @@ #include namespace json { - + class Value; class Reader; class Writer; //types used by Value - typedef int TInteger; - typedef unsigned int TUInteger; + typedef long int TInteger; + typedef unsigned long int TUInteger; typedef double TReal; typedef bool TBool; typedef std::string TString; typedef std::map TObject; typedef std::vector TArray; - + typedef union { //basic types by value TInteger integer; @@ -46,7 +46,7 @@ namespace json { TReal real; TBool boolean; //structured types by reference - TString *_string; + TString *string; TObject *object; TArray *array; } TData; @@ -62,29 +62,36 @@ namespace json { TARRAY, TNULL }; - + //JSON Value container class. Basic types (int,uint,real,bool) are stored by value, and structured types are stored by reference. class Value { - + friend class Reader; friend class Writer; - + public: - + // Default constructs null Value (this is fast) inline Value() : refcount(NULL), type(TNULL) { } - + + // Initilize to be of a specific type + inline Value(Type type_) : refcount(NULL), type(TNULL) { reset(type_); } + // Construct values directly from basic types. These are passed by value and have no refcount. explicit inline Value(TInteger integer) : refcount(NULL), type(TINTEGER) { data.integer = integer; } explicit inline Value(TUInteger uinteger) : refcount(NULL), type(TUINTEGER) { data.uinteger = uinteger; } explicit inline Value(TReal real) : refcount(NULL), type(TREAL) { data.real = real; } explicit inline Value(TBool boolean) : refcount(NULL), type(TBOOL) { data.boolean = boolean; } - + + // All these integer types... force them into our types + explicit inline Value(unsigned int uinteger) : refcount(NULL), type(TUINTEGER) { data.uinteger = (TUInteger)uinteger; } + explicit inline Value(int integer) : refcount(NULL), type(TINTEGER) { data.integer = (TInteger)integer; } + // Construct structured types. These values are copied into the Value and subsequently passed by reference with refcount. - explicit inline Value(TString string) : refcount(new TUInteger(0)), type(TSTRING) { data._string = new TString(string); } + explicit inline Value(TString string) : refcount(new TUInteger(0)), type(TSTRING) { data.string = new TString(string); } explicit inline Value(TObject object) : refcount(new TUInteger(0)), type(TOBJECT) { data.object = new TObject(object); } explicit inline Value(TArray array) : refcount(new TUInteger(0)), type(TARRAY) { data.array = new TArray(array); } - + // Constructs a JSON array from a vector (assuming the compile type conversions are possible) template Value(const std::vector &ref) : refcount(new TUInteger(0)), type(TARRAY) { const size_t size = ref.size(); @@ -93,52 +100,52 @@ namespace json { (*data.array)[i] = Value(ref[i]); } } - + // Copy constructor - preserves structured types and refcount tracking inline Value(const Value &other) : refcount(other.refcount), type(other.type), data(other.data) { incref(); } - + // Destructor handles refcount tracking of structured types inline ~Value() { decref(); } - + // Sets the lhs equal to the value (for base types) or reference (for structured types) inline Value& operator=(const Value& other) { decref(); data = other.data; type = other.type; refcount = other.refcount; incref(); return *this; } template inline Value& operator=(const T& val) { return operator=(Value(val)); } - + inline Value& operator[](const std::string &key) const { return getMember(key); } inline Value& operator[](const size_t index) const { return getIndex(index); } - + // Initializes the state of the Value to the default for structured types or unspecified for basic types void reset(Type type); - + // Sets the value to null inline void reset() { reset(TNULL); } - + // Returns the type of the Value inline Type getType() const { return type; } - + // Getters will throw a parser_error if the type of the Value is not the requested type inline TInteger getInteger() const { checkType(TINTEGER); return data.integer; } inline TUInteger getUInteger() const { checkType(TUINTEGER); return data.uinteger; } inline TReal getReal() const { checkType(TREAL); return data.real; } inline TBool getBool() const { checkType(TBOOL); return data.boolean; } - inline TString getString() const { checkType(TSTRING); return *data._string; } - + inline TString getString() const { checkType(TSTRING); return *data.string; } + // Returns a member of a JSON object inline Value& getMember(TString key) const { checkType(TOBJECT); return (*data.object)[key]; } - + // Returns the size of a JSON array inline size_t getArraySize() const { checkType(TARRAY); return data.array->size(); } - + // Returns the Value at an index in a JSON array inline Value& getIndex(size_t index) const { checkType(TARRAY); return (*data.array)[index]; } - + #ifndef __CINT__ - // Templated casting functions (use these when possible / see below for default specializations) + // Templated casting functions (use these when possible / see below for default specializations) template inline T cast() const { throw std::runtime_error("Cannot cast Value to desired type"); // Arbitrary type casts are impossible } - + // Templated vector constructing method (uses templated casters to convert types) template inline std::vector toVector() const { const size_t size = getArraySize(); //will check that we are an array @@ -150,64 +157,64 @@ namespace json { } #endif - + // Returns a vector of all the keys in the JSON object std::vector getMembers() const; - + // Returns true if the key exists in the JSON object bool isMember(std::string key) const; - + // Setters will reset the type if necessary inline void setInteger(TInteger integer) { checkTypeReset(TINTEGER); data.integer = integer; } inline void setUINteger(TUInteger uinteger) { checkTypeReset(TUINTEGER); data.uinteger = uinteger; } inline void setReal(TReal real) { checkTypeReset(TREAL); data.real = real; } inline void setReal(TBool boolean) { checkTypeReset(TBOOL); data.boolean = boolean; } - inline void setString(TString string) { checkTypeReset(TSTRING); *data._string = string; } - - // Sets a member of a JSON object + inline void setString(TString string) { checkTypeReset(TSTRING); *data.string = string; } + + // Sets a member of a JSON object inline void setMember(TString key, Value value) { checkTypeReset(TOBJECT); (*data.object)[key] = value; } - - // Sets the size of a JSON array + + // Sets the size of a JSON array inline void setArraySize(size_t size) { checkTypeReset(TARRAY); data.array->resize(size); } - + // Sets the Value at an index in a JSON array inline void setIndex(size_t index, Value value) { checkTypeReset(TARRAY); (*data.array)[index] = value; } - + protected: - + // Returns a string representing the given type static std::string prettyType(Type type); - + // Throws a nice error message for trying to get the wrong type static void wrongType(Type actual, Type requested); - + // Throws a runtime_error if the type of the Value does not match the given Type - inline void checkType(Type _type) const { if (this->type != _type) { wrongType(this->type, _type); } } - + inline void checkType(Type type_) const { if (this->type != type_) { wrongType(this->type,type_); } } + // Resets the type of Value of the current type does not match the given Type - inline void checkTypeReset(Type _type) { if (this->type != _type) reset(TOBJECT); } - + inline void checkTypeReset(Type type_) { if (this->type != type_) reset(TOBJECT); } + // Decreases the refcount of the Value and cleans up if necessary inline void decref() { if (refcount && !((*refcount)--)) clean(); } - + // Increases the refcount of the Value if necessary inline void incref() { if (refcount) (*refcount)++; } - + // Frees any allocated memory for this object and resets to null void clean(); - + // Pointer to the number of references of a structured type TUInteger *refcount; - + // The current type of the Value Type type; - + // Union to hold the data with minimal space requirements TData data; }; - + #ifndef __CINT__ - + // Everything can be cast to a string in one way or another template <> inline std::string Value::cast() const { switch (type) { @@ -228,7 +235,7 @@ namespace json { case TNULL: return "null"; case TSTRING: - return *(data._string); + return *(data.string); case TARRAY: { std::stringstream out; out << "ARR{" << (void*)data.array << '}'; return out.str(); @@ -241,8 +248,8 @@ namespace json { throw std::runtime_error("Value could not be cast to string (forgotten?)"); } } - - // Only integer Values can be cast as ints + + // Only integer Values can be cast as ints (typically 32 bits) template <> inline int Value::cast() const { switch (type) { case TUINTEGER: @@ -253,9 +260,9 @@ namespace json { throw std::runtime_error("Cannot cast " + prettyType(type) + " to integer"); } } - + // All numerics can be cast to doubles - template <> inline double Value::cast() const { + template <> inline double Value::cast() const { switch (type) { case TUINTEGER: return data.uinteger; @@ -267,9 +274,9 @@ namespace json { throw std::runtime_error("Cannot cast " + prettyType(type) + " to double"); } } - + // All Values are true except zero, false, and null - template <> inline bool Value::cast() const { + template <> inline bool Value::cast() const { switch (type) { case TUINTEGER: return data.uinteger != 0; @@ -287,7 +294,7 @@ namespace json { } #endif - + //represents errors in parsing JSON values class parser_error : public std::exception { public: @@ -298,62 +305,65 @@ namespace json { const int line, pos; std::string desc, pretty; }; - + //parses JSON values from a stream class Reader { public: - //Reads the entire stream immediately + //Reads entire stream into internal buffer immediately Reader(std::istream &stream); - - //Copies the string into the internal buffer + + //Copies the entire string into an internal buffer Reader(const std::string &str); - + ~Reader(); - + //Returns the next value in the stream bool getValue(Value &result); - + protected: //Positional data in the stream data (gets garbled during parsing) char *data,*cur,*lastbr; int line; - + //Converts an escaped JSON string into its literal representation std::string unescapeString(std::string string); - + //Helpers to read JSON types Value readNumber(); Value readString(); Value readObject(); Value readArray(); - + void skipComment(); - + }; - + //writes JSON values to a stream class Writer { public: //Only writes to the stream when requested Writer(std::ostream &stream); - + ~Writer(); - - //Writes a value to the stream - void putValue(Value value); - + + //This produces JSON compliant output at the expense of: + //***Unsigned integers get printed as base 10 numbers, and the next parser may truncate into signed + //Ultimately produces object-indented text with value-per-line mentality with arrays on a single line + //which is similar enough to how RATDB looks without too much effort. + void putValue(const Value &value); + protected: //The stream to write to std::ostream &out; - + //Converts a literal string to its escaped representation std::string escapeString(std::string string); - + //Helper to write a value to the stream - void writeValue(Value value); - - }; - + void writeValue(const Value &value, const std::string &depth = ""); + + }; + } #endif diff --git a/src/db/src/DB.cc b/src/db/src/DB.cc index b7c627aa..65f25900 100644 --- a/src/db/src/DB.cc +++ b/src/db/src/DB.cc @@ -404,6 +404,9 @@ DBTable *DB::FindTable(std::string tblname, std::string index, int runNumber) } } + /* + // This code was not actually doing anything because the bytes were not being + // tracked before in the first place, but keep commented for historical reasons. // 5) Flush out some tables if we need the space int newTableBytes = newTable->GetBytes(); int serverTableBytes = 0; @@ -421,6 +424,7 @@ DBTable *DB::FindTable(std::string tblname, std::string index, int runNumber) tables.erase(forDeletion.first); cerr << "Evicting " << forDeletion.first.name << "[" << forDeletion.first.index << "], run " << forDeletion.first.run << " (" << deleteSize << " bytes)\n"; } + */ // 6) Add this table to the memory cache simple_ptr_nocopy newTablePtr(newTable); @@ -442,45 +446,6 @@ DBTable *DB::FindTable(std::string tblname, std::string index, int runNumber) return newTable; } -void DB::SetI(std::string tblname, std::string index, std::string fieldname, int val) -{ - DBTable *t = FindOrCreateTable(tblname, index, -1); - t->SetI(fieldname, val); -} - -void DB::SetD(std::string tblname, std::string index, std::string fieldname, double val) -{ - DBTable *t = FindOrCreateTable(tblname, index, -1); - t->SetD(fieldname, val); -} - - -void DB::SetS(std::string tblname, std::string index, std::string fieldname, std::string val) -{ - DBTable *t = FindOrCreateTable(tblname, index, -1); - t->SetS(fieldname, val); -} - - -void DB::SetIArray(std::string tblname, std::string index, std::string fieldname, const std::vector &val) -{ - DBTable *t = FindOrCreateTable(tblname, index, -1); - t->SetIArray(fieldname, val); -} - -void DB::SetDArray(std::string tblname, std::string index, std::string fieldname, const std::vector &val) -{ - DBTable *t = FindOrCreateTable(tblname, index, -1); - t->SetDArray(fieldname, val); -} - -void DB::SetSArray(std::string tblname, std::string index, std::string fieldname, const std::vector &val) -{ - DBTable *t = FindOrCreateTable(tblname, index, -1); - t->SetSArray(fieldname, val); -} - - DBTable *DB::FindOrCreateTable(std::string tblname, std::string index, int runNumber) { DBTable *table = FindTable(tblname, index, runNumber); diff --git a/src/db/src/DBLink.cc b/src/db/src/DBLink.cc index ff90ca18..2861be06 100644 --- a/src/db/src/DBLink.cc +++ b/src/db/src/DBLink.cc @@ -26,23 +26,29 @@ DBLink::~DBLink() int DBLink::GetI(const std::string &name) { - return Pick(name, DBTable::INTEGER); + return Get(name); } double DBLink::GetD(const std::string &name) { - return Pick(name, DBTable::DOUBLE); + return Get(name); } std::string DBLink::GetS(const std::string &name) { - return Pick(name, DBTable::STRING); + return Get(name); } +bool DBLink::GetZ(const std::string &name) +{ + return Get(name); +} + + std::vector DBLink::GetIArray(const std::string &name) { - return Pick< std::vector >(name, DBTable::INTEGER_ARRAY); + return Get >(name); } @@ -70,55 +76,23 @@ std::vector DBLink::DArrayToFArray(const std::vector &input) std::vector DBLink::GetDArray(const std::string &name) { - return Pick< std::vector >(name, DBTable::DOUBLE_ARRAY); + return Get >(name); } std::vector DBLink::GetSArray(const std::string &name) { - return Pick< std::vector >(name, DBTable::STRING_ARRAY); + return Get >(name); } -json::Value DBLink::GetJSON(const std::string &name) +std::vector DBLink::GetZArray(const std::string &name) { - return Pick< json::Value >(name, DBTable::JSON); + return Get >(name); } -// Helper function to make Pick() easier to read -// Type equality is as you would expect, but JSON equals everything except NOTFOUND -inline bool equivalent(DBTable::FieldType a, DBTable::FieldType b) -{ - if (a == b) return true; - else if (a == DBTable::JSON && b != DBTable::NOTFOUND) return true; - else if (b == DBTable::JSON && a != DBTable::NOTFOUND) return true; - else return false; -} -template -T DBLink::Pick(std::string fieldname, DBTable::FieldType ftype) const +json::Value DBLink::GetJSON(const std::string &name) { - DBTable *tbl; - - // First try user plane - tbl = db->GetUserTable(tblname, index); - if (!tbl || !equivalent(tbl->GetFieldType(fieldname), ftype)) { - // Then try the run plane - tbl = db->GetRunTable(tblname, index, currentRun); - if(!tbl || !equivalent(tbl->GetFieldType(fieldname), ftype)) { - - // Finally try default plane - tbl = db->GetDefaultTable(tblname, index); - if (!tbl || !equivalent(tbl->GetFieldType(fieldname), ftype)) - throw DBNotFoundError(tblname, index, fieldname); - } - } - - // Make class explicit to satisfy Sun CC 5.3 - T value = tbl->DBTable::Get(fieldname); - - // Trace DB accesses - Log::TraceDBAccess(tblname, index, fieldname, value); - - return value; + return Get(name); } diff --git a/src/db/src/DBTable.cc b/src/db/src/DBTable.cc index e5f213c6..5f75bec8 100644 --- a/src/db/src/DBTable.cc +++ b/src/db/src/DBTable.cc @@ -4,7 +4,7 @@ namespace RAT { DBTable::DBTable() - : tblname(""), index(""), run_begin(0), run_end(0), bytes(0) + : tblname(""), index(""), run_begin(0), run_end(0) { this->tblname = ""; this->index = ""; @@ -12,7 +12,7 @@ DBTable::DBTable() } DBTable::DBTable(json::Value &jsonDoc) - : tblname(""), index(""), run_begin(0), run_end(0), bytes(0) + : tblname(""), index(""), run_begin(0), run_end(0) { tblname = jsonDoc["name"].cast(); if (jsonDoc.isMember("index")) @@ -25,7 +25,7 @@ DBTable::DBTable(json::Value &jsonDoc) } DBTable::DBTable(std::string _tblname, std::string _index) - : tblname(_tblname), index(_index), run_begin(0), run_end(0), bytes(0) + : tblname(_tblname), index(_index), run_begin(0), run_end(0) { table.reset(json::TOBJECT); } @@ -46,8 +46,9 @@ DBTable::FieldType DBTable::GetFieldType(std::string name) const switch (val.getType()) { case json::TINTEGER: case json::TUINTEGER: - case json::TBOOL: return DBTable::INTEGER; + case json::TBOOL: + return DBTable::BOOLEAN; case json::TREAL: return DBTable::DOUBLE; case json::TSTRING: @@ -57,8 +58,9 @@ DBTable::FieldType DBTable::GetFieldType(std::string name) const switch (val[0].getType()) { case json::TINTEGER: case json::TUINTEGER: - case json::TBOOL: return DBTable::INTEGER_ARRAY; + case json::TBOOL: + return DBTable::BOOLEAN_ARRAY; case json::TREAL: return DBTable::DOUBLE_ARRAY; case json::TSTRING: @@ -122,27 +124,20 @@ std::string DBTable::GetS(const std::string &name) const { return table[name].cast(); } -std::vector DBTable::GetSArray(const std::string &name) const { +bool DBTable::GetZ(const std::string &name) const { if (!table.isMember(name)) throw DBNotFoundError(tblname, index, name); - else if (GetFieldType(name) != STRING_ARRAY) - throw DBWrongTypeError(tblname, index, name, STRING_ARRAY, GetFieldType(name)); + else if (table[name].getType() != json::TBOOL) + throw DBWrongTypeError(tblname, index, name, BOOLEAN, GetFieldType(name)); else - return table[name].toVector(); -} - -json::Value DBTable::GetJSON(const std::string &name) const { - if (!table.isMember(name)) - throw DBNotFoundError(tblname, index, name); - else - return table[name]; + return table[name].cast(); } std::vector DBTable::GetIArray(const std::string &name) const { // Fetch if deferred DBTable *me = const_cast(this); // grumble, grumble if (me->iatbl_deferred.present(name)) { - me->SetIArray(name, me->iatbl_deferred[name]->FetchIArray(GetS("_id"), name)); + me->Set(name, me->iatbl_deferred[name]->FetchIArray(GetS("_id"), name)); me->iatbl_deferred.erase(name); } @@ -160,21 +155,51 @@ std::vector DBTable::GetDArray(const std::string &name) const { // Fetch if deferred DBTable *me = const_cast(this); // grumble, grumble if (me->datbl_deferred.present(name)) { - me->SetDArray(name, me->datbl_deferred[name]->FetchDArray(GetS("_id"), name)); + me->Set(name, me->datbl_deferred[name]->FetchDArray(GetS("_id"), name)); me->datbl_deferred.erase(name); } - if (!table.isMember(name)) + if (!table.isMember(name)) { throw DBNotFoundError(tblname, index, name); - else if (GetFieldType(name) != DOUBLE_ARRAY) + } else if (GetFieldType(name) == INTEGER_ARRAY) { + const std::vector iv = GetIArray(name); + std::vector v(iv.size()); + for (size_t i = 0; i < iv.size(); i++) { + v[i] = iv[i]; + } + return v; + } else if (GetFieldType(name) != DOUBLE_ARRAY) { throw DBWrongTypeError(tblname, index, name, DOUBLE_ARRAY, GetFieldType(name)); - else { + } else { const json::Value &json_array = table[name]; return json_array.toVector(); } } +std::vector DBTable::GetSArray(const std::string &name) const { + if (!table.isMember(name)) + throw DBNotFoundError(tblname, index, name); + else if (GetFieldType(name) != STRING_ARRAY) + throw DBWrongTypeError(tblname, index, name, STRING_ARRAY, GetFieldType(name)); + else + return table[name].toVector(); +} + +std::vector DBTable::GetZArray(const std::string &name) const { + if (!table.isMember(name)) + throw DBNotFoundError(tblname, index, name); + else if (GetFieldType(name) != BOOLEAN_ARRAY) + throw DBWrongTypeError(tblname, index, name, BOOLEAN_ARRAY, GetFieldType(name)); + else + return table[name].toVector(); +} +json::Value DBTable::GetJSON(const std::string &name) const { + if (!table.isMember(name)) + throw DBNotFoundError(tblname, index, name); + else + return table[name]; +} } // namespace RAT diff --git a/src/db/src/DBTextLoader.cc b/src/db/src/DBTextLoader.cc index 388142f4..2100528c 100644 --- a/src/db/src/DBTextLoader.cc +++ b/src/db/src/DBTextLoader.cc @@ -360,11 +360,11 @@ DBTable *Parser::Next() state = STATE_VAL; switch (toktype) { - case Tokenizer::TYPE_STRING: tbl->SetS(identifier, tokenizer.Token()); + case Tokenizer::TYPE_STRING: tbl->Set(identifier, tokenizer.Token()); break; - case Tokenizer::TYPE_INTEGER: tbl->SetI(identifier, tokenizer.AsInt()); + case Tokenizer::TYPE_INTEGER: tbl->Set(identifier, tokenizer.AsInt()); break; - case Tokenizer::TYPE_DOUBLE: tbl->SetD(identifier, tokenizer.AsDouble()); + case Tokenizer::TYPE_DOUBLE: tbl->Set(identifier, tokenizer.AsDouble()); break; default: assert(0); // should never get here @@ -416,9 +416,9 @@ DBTable *Parser::Next() // Allow array to be closed after a comma (to be nice) state = STATE_VAL; switch (array_type) { - case Tokenizer::TYPE_STRING: tbl->SetSArray(identifier, string_array); break; - case Tokenizer::TYPE_INTEGER: tbl->SetIArray(identifier, integer_array); break; - case Tokenizer::TYPE_DOUBLE: tbl->SetDArray(identifier, double_array); break; + case Tokenizer::TYPE_STRING: tbl->Set(identifier, string_array); break; + case Tokenizer::TYPE_INTEGER: tbl->Set(identifier, integer_array); break; + case Tokenizer::TYPE_DOUBLE: tbl->Set(identifier, double_array); break; case Tokenizer::TYPE_ERROR: tokenizer.RaiseError("Empty arrays not allowed"); break; @@ -436,9 +436,9 @@ DBTable *Parser::Next() && tokenizer.Token() == "]") { state = STATE_VAL; switch (array_type) { - case Tokenizer::TYPE_STRING: tbl->SetSArray(identifier, string_array); break; - case Tokenizer::TYPE_INTEGER: tbl->SetIArray(identifier, integer_array); break; - case Tokenizer::TYPE_DOUBLE: tbl->SetDArray(identifier, double_array); break; + case Tokenizer::TYPE_STRING: tbl->Set(identifier, string_array); break; + case Tokenizer::TYPE_INTEGER: tbl->Set(identifier, integer_array); break; + case Tokenizer::TYPE_DOUBLE: tbl->Set(identifier, double_array); break; case Tokenizer::TYPE_ERROR: tokenizer.RaiseError("Empty array not allowed"); break; @@ -570,13 +570,13 @@ std::vector DBTextLoader::parse(std::string filename) run_range[0] = run_range[1] = 0; // Add modern run_range field - table->SetIArray("run_range", run_range); + table->Set("run_range", run_range); table->SetRunRange(run_range[0], run_range[1]); } else if (valid_begin[0] == -1 && valid_begin[1] == -1 && valid_end[0] == -1 && valid_end[1] == -1) { run_range[0] = run_range[1] = -1; // Add modern run_range field - table->SetIArray("run_range", run_range); + table->Set("run_range", run_range); table->SetRunRange(run_range[0], run_range[1]); } else { cerr << "Table has old-style valid_begin/valid_end arrays not set to default or user plane. Discarding..." diff --git a/src/db/src/json.cc b/src/db/src/json.cc index ba7eb8aa..d60cb073 100644 --- a/src/db/src/json.cc +++ b/src/db/src/json.cc @@ -15,21 +15,23 @@ * along with fastjson. If not, see . */ -#include "RAT/json.hh" +#include #include #include #include #include +#include +#include namespace json { - void Value::reset(Type _type) { + void Value::reset(Type type_) { decref(); - this->type = _type; - switch (_type) { + this->type = type_; + switch (type) { case TSTRING: - data._string = new TString(); + data.string = new TString(); refcount = new TUInteger(0); return; case TOBJECT: @@ -49,7 +51,7 @@ namespace json { if (refcount) delete refcount; switch (type) { case TSTRING: - delete data._string; + delete data.string; break; case TOBJECT: delete data.object; @@ -98,7 +100,7 @@ namespace json { case TNULL: return "TNULL"; default: - return "UNKNOWN"; + return "ERROR"; } } @@ -144,7 +146,7 @@ namespace json { } Reader::~Reader() { - delete [] data; + delete[] data; } bool Reader::getValue(Value &result) { @@ -282,12 +284,14 @@ namespace json { default: { char next = *cur; *cur = '\0'; - TUInteger hex; - std::stringstream temp; - temp << std::hex << start; - temp >> hex; + errno = 0; + char *end; + TUInteger ui = strtoul(start,&end,16); + if (end != cur) throw parser_error(line,cur-lastbr,"Malformed hex number"); + if (ui == ULONG_MAX && errno == ERANGE) + throw parser_error(line,cur-lastbr,"Unsigned integer out of bounds."); *cur = next; - return Value(hex); + return Value(ui); } } } @@ -301,7 +305,12 @@ namespace json { case 'u': //non-json explicit unsigned *cur = '\0'; cur++; - return Value((TUInteger)atoi(start)); + { + char *end; + Value v((TUInteger)strtoul(start,&end,10)); + if (end != cur-1) throw parser_error(line,cur-lastbr,"Malformed integer"); + return v; + } case 'd': //non-json explicit real OR strange exponential switch (cur[1]) { case '+': @@ -328,7 +337,12 @@ namespace json { case 'f': //non-json explicit real *cur = '\0'; cur++; - return Value((TReal)atof(start)); + { + char *end; + Value v((TReal)strtod(start,&end)); + if (end != cur-1) throw parser_error(line,cur-lastbr,"Malformed real"); + return v; + } case '.': //real real = true; case '+': @@ -350,9 +364,25 @@ namespace json { *cur = '\0'; Value val; if (real || exp) { - val = Value((TReal)atof(start)); + char *end; + val = Value((TReal)strtod(start,&end)); + if (end != cur) throw parser_error(line,cur-lastbr,"Malformed real"); } else { - val = Value((TInteger)atoi(start)); + errno = 0; + char *end; + TInteger i = strtol(start,&end,10); + if (end != cur) throw parser_error(line,cur-lastbr,"Malformed integer"); + if (i == LONG_MIN && errno == ERANGE) + throw parser_error(line,cur-lastbr,"Signed integer out of bounds."); + if (i == LONG_MAX && errno == ERANGE) { + errno = 0; + TUInteger ui = strtoul(start,NULL,10); + if (ui == ULONG_MAX && errno == ERANGE) + throw parser_error(line,cur-lastbr,"Unsigned integer out of bounds."); + val = Value(ui); + } else { + val = Value(i); + } } *cur = next; return val; @@ -507,46 +537,54 @@ namespace json { } - void Writer::putValue(Value value) { - writeValue(value); + void Writer::putValue(const Value &value) { + writeValue(value,""); out << '\n'; } - //This could make prettier output - void Writer::writeValue(Value value) { + void Writer::writeValue(const Value &value, const std::string &depth) { switch (value.type) { case TINTEGER: out << value.data.integer; break; case TUINTEGER: - out << value.data.uinteger << 'u'; + out << value.data.uinteger; break; case TREAL: out.precision(std::numeric_limits::digits10); out << value.data.real; break; case TSTRING: - out << '"' << escapeString(*(value.data._string)) << '"'; + out << '"' << escapeString(*(value.data.string)) << '"'; break; case TOBJECT: { + const std::string nextdepth(depth+" "); TObject::iterator it = value.data.object->begin(); TObject::iterator end = value.data.object->end(); out << "{\n"; - for ( ; it != end; ++it) { - out << '\"' << it->first << "\" : "; - writeValue(it->second); - out << ",\n"; + if (it != end) { + out << nextdepth << '\"' << it->first << "\" : "; + writeValue(it->second,nextdepth); + it++; } - out << '}'; + for ( ; it != end; it++) { + out << ",\n" << nextdepth << '\"' << it->first << "\" : "; + writeValue(it->second,nextdepth); + } + out << '\n' << depth << '}'; } break; case TARRAY: { TArray::iterator it = value.data.array->begin(); TArray::iterator end = value.data.array->end(); out << '['; - for ( ; it != end; ++it) { + if (it != end) { writeValue(*it); + it++; + } + for ( ; it != end; it++) { out << ", "; + writeValue(*it); } out << ']'; } diff --git a/src/geo/src/TheiaDetectorFactory.cc b/src/geo/src/TheiaDetectorFactory.cc index 69ee1e0e..7cedb4ec 100644 --- a/src/geo/src/TheiaDetectorFactory.cc +++ b/src/geo/src/TheiaDetectorFactory.cc @@ -193,28 +193,28 @@ void TheiaDetectorFactory::DefineDetector(DBLinkPtr /*detector*/) { vector world_size(3); world_size[0] = world_size[1] = det_radius+10000.0; world_size[2] = det_halfheight+10000.0; - db->SetDArray("GEO","world","size",world_size); - db->SetD("GEO","tank","r_max",det_radius+tank_thickness); - db->SetD("GEO","tank","size_z",det_halfheight+tank_thickness); - db->SetD("GEO","detector","r_max",det_radius); - db->SetD("GEO","detector","size_z",det_halfheight); + db->Set("GEO","world","size",world_size); + db->Set("GEO","tank","r_max",det_radius+tank_thickness); + db->Set("GEO","tank","size_z",det_halfheight+tank_thickness); + db->Set("GEO","detector","r_max",det_radius); + db->Set("GEO","detector","size_z",det_halfheight); info << "Generating PMTINFO...\n"; - db->SetDArray("PMTINFO","x",x); - db->SetDArray("PMTINFO","y",y); - db->SetDArray("PMTINFO","z",z); - db->SetDArray("PMTINFO","dir_x",dir_x); - db->SetDArray("PMTINFO","dir_y",dir_y); - db->SetDArray("PMTINFO","dir_z",dir_z); - db->SetIArray("PMTINFO","type",type); + db->Set("PMTINFO","x",x); + db->Set("PMTINFO","y",y); + db->Set("PMTINFO","z",z); + db->Set("PMTINFO","dir_x",dir_x); + db->Set("PMTINFO","dir_y",dir_y); + db->Set("PMTINFO","dir_z",dir_z); + db->Set("PMTINFO","type",type); info << "Update geometry fields related to veto PMTs...\n"; - db->SetI("GEO","veto_pmts","start_idx",num_pmts); - db->SetI("GEO","veto_pmts","end_idx",total_pmts-1); + db->Set("GEO","veto_pmts","start_idx",num_pmts); + db->Set("GEO","veto_pmts","end_idx",total_pmts-1); info << "Update geometry fields related to normal PMTs...\n"; - db->SetI("GEO","inner_pmts","start_idx",0); - db->SetI("GEO","inner_pmts","end_idx",num_pmts-1); + db->Set("GEO","inner_pmts","start_idx",0); + db->Set("GEO","inner_pmts","end_idx",num_pmts-1); } diff --git a/src/geo/src/WatchmanDetectorFactory.cc b/src/geo/src/WatchmanDetectorFactory.cc index 4ebbd38c..76e54282 100644 --- a/src/geo/src/WatchmanDetectorFactory.cc +++ b/src/geo/src/WatchmanDetectorFactory.cc @@ -196,21 +196,21 @@ namespace RAT { info << "Update geometry fields related to the reflective and absorptive tarps...\n"; // Side tarps - db->SetD("GEO","white_sheet_side","r_max",veto_radius); - db->SetD("GEO","white_sheet_side","r_min",veto_radius-10.0); // Marc Bergevin: Hardcoding in a 1 cm value for thickness - db->SetD("GEO","white_sheet_side","size_z",topbot_veto_offset); + db->Set("GEO","white_sheet_side","r_max",veto_radius); + db->Set("GEO","white_sheet_side","r_min",veto_radius-10.0); // Marc Bergevin: Hardcoding in a 1 cm value for thickness + db->Set("GEO","white_sheet_side","size_z",topbot_veto_offset); - db->SetD("GEO","black_sheet_side","r_max",pmt_radius+black_sheet_offset+black_sheet_thickness); //paige kunkle: expanding black tarp (+30cm) // Marc Bergevin: Hardcoding in a 1 cm value for thickness - db->SetD("GEO","black_sheet_side","r_min",pmt_radius+black_sheet_offset); //paige kunkle: expanding black tarp (+30cm) - db->SetD("GEO","black_sheet_side","size_z",topbot_offset+black_sheet_offset);//paige kunkle: expanding black tarp (+30cm) + db->Set("GEO","black_sheet_side","r_max",pmt_radius+black_sheet_offset+black_sheet_thickness); //paige kunkle: expanding black tarp (+30cm) // Marc Bergevin: Hardcoding in a 1 cm value for thickness + db->Set("GEO","black_sheet_side","r_min",pmt_radius+black_sheet_offset); //paige kunkle: expanding black tarp (+30cm) + db->Set("GEO","black_sheet_side","size_z",topbot_offset+black_sheet_offset);//paige kunkle: expanding black tarp (+30cm) - db->SetD("GEO","Rod_assemblies","r_max",(pmt_radius+300.)); // Based on Geofile thickness values of 10 cm - db->SetD("GEO","Rod_assemblies","r_min",(pmt_radius+200.)); - db->SetD("GEO","Rod_assemblies","size_z",topbot_offset); + db->Set("GEO","Rod_assemblies","r_max",(pmt_radius+300.)); // Based on Geofile thickness values of 10 cm + db->Set("GEO","Rod_assemblies","r_min",(pmt_radius+200.)); + db->Set("GEO","Rod_assemblies","size_z",topbot_offset); - db->SetD("GEO","white_sheet_tank_side","r_max",detector_size_d/2.0 -10.0); - db->SetD("GEO","white_sheet_tank_side","r_min",detector_size_d/2.0 -35.0); - db->SetD("GEO","white_sheet_tank_side","size_z",detector_size_z/2.0-35.0); + db->Set("GEO","white_sheet_tank_side","r_max",detector_size_d/2.0 -10.0); + db->Set("GEO","white_sheet_tank_side","r_min",detector_size_d/2.0 -35.0); + db->Set("GEO","white_sheet_tank_side","size_z",detector_size_z/2.0-35.0); //Top tarps @@ -241,18 +241,18 @@ namespace RAT { - db->SetD("GEO","white_sheet_top","r_max",veto_radius); - db->SetDArray("GEO","white_sheet_top","position",move_white_top); - db->SetD("GEO","black_sheet_top","r_max",pmt_radius+black_sheet_offset);//paige kunkle: expanding black tarp (+30cm) - db->SetDArray("GEO","black_sheet_top","position",move_black_top); - db->SetD("GEO","Top_cap_framework","r_max",pmt_radius); - db->SetDArray("GEO","Top_cap_framework","position",move_topcap); - db->SetD("GEO","Wall_support_truss_top","r_min",pmt_radius+5.0); // Bergevin: Values based - db->SetD("GEO","Wall_support_truss_top","r_max",pmt_radius+200.0);// on geofile - db->SetDArray("GEO","Wall_support_truss_top","position",move_toptruss); + db->Set("GEO","white_sheet_top","r_max",veto_radius); + db->Set("GEO","white_sheet_top","position",move_white_top); + db->Set("GEO","black_sheet_top","r_max",pmt_radius+black_sheet_offset);//paige kunkle: expanding black tarp (+30cm) + db->Set("GEO","black_sheet_top","position",move_black_top); + db->Set("GEO","Top_cap_framework","r_max",pmt_radius); + db->Set("GEO","Top_cap_framework","position",move_topcap); + db->Set("GEO","Wall_support_truss_top","r_min",pmt_radius+5.0); // Bergevin: Values based + db->Set("GEO","Wall_support_truss_top","r_max",pmt_radius+200.0);// on geofile + db->Set("GEO","Wall_support_truss_top","position",move_toptruss); - db->SetD("GEO","white_sheet_tank_top","r_max",detector_size_d/2.0 -35.0); - db->SetDArray("GEO","white_sheet_tank_top","position",move_toptanktarp); + db->Set("GEO","white_sheet_tank_top","r_max",detector_size_d/2.0 -35.0); + db->Set("GEO","white_sheet_tank_top","position",move_toptanktarp); @@ -282,18 +282,18 @@ namespace RAT { - db->SetD("GEO","white_sheet_bottom","r_max",veto_radius); - db->SetDArray("GEO","white_sheet_bottom","position",move_white_bottom); - db->SetD("GEO","black_sheet_bottom","r_max",pmt_radius+black_sheet_offset);//paige kunkle: expanding black tarp (+30cm) - db->SetDArray("GEO","black_sheet_bottom","position",move_black_bottom); - db->SetD("GEO","Bottom_cap_framework","r_max",pmt_radius); - db->SetDArray("GEO","Bottom_cap_framework","position",move_bottomcap); - db->SetD("GEO","Wall_support_truss_bottom","r_min",pmt_radius+5.0); // Bergevin: Values based - db->SetD("GEO","Wall_support_truss_bottom","r_max",pmt_radius+200.0);// on geofile - db->SetDArray("GEO","Wall_support_truss_bottom","position",move_bottomtruss); + db->Set("GEO","white_sheet_bottom","r_max",veto_radius); + db->Set("GEO","white_sheet_bottom","position",move_white_bottom); + db->Set("GEO","black_sheet_bottom","r_max",pmt_radius+black_sheet_offset);//paige kunkle: expanding black tarp (+30cm) + db->Set("GEO","black_sheet_bottom","position",move_black_bottom); + db->Set("GEO","Bottom_cap_framework","r_max",pmt_radius); + db->Set("GEO","Bottom_cap_framework","position",move_bottomcap); + db->Set("GEO","Wall_support_truss_bottom","r_min",pmt_radius+5.0); // Bergevin: Values based + db->Set("GEO","Wall_support_truss_bottom","r_max",pmt_radius+200.0);// on geofile + db->Set("GEO","Wall_support_truss_bottom","position",move_bottomtruss); - db->SetD("GEO","white_sheet_tank_bottom","r_max",detector_size_d/2.0 -35.0); - db->SetDArray("GEO","white_sheet_tank_bottom","position",move_bottomtanktarp); + db->Set("GEO","white_sheet_tank_bottom","r_max",detector_size_d/2.0 -35.0); + db->Set("GEO","white_sheet_tank_bottom","position",move_bottomtanktarp); info << "Adjusting the Bottom cap standoff frames ...\n"; @@ -346,51 +346,51 @@ namespace RAT { info << "New size " << standoff_frame_4_size[0] << " " << standoff_frame_4_size[1] << " " << standoff_frame_4_size[2] << "...\n"; } - db->SetDArray("GEO","Bottom_cap_standoff_frame_0","size",standoff_frame_0_size); - db->SetDArray("GEO","Bottom_cap_standoff_frame_0","position",standoff_frame_0_pos); - db->SetDArray("GEO","Bottom_cap_standoff_frame_1","size",standoff_frame_1_size); - db->SetDArray("GEO","Bottom_cap_standoff_frame_1","position",standoff_frame_1_pos); - db->SetDArray("GEO","Bottom_cap_standoff_frame_2","size",standoff_frame_2_size); - db->SetDArray("GEO","Bottom_cap_standoff_frame_2","position",standoff_frame_2_pos); - db->SetDArray("GEO","Bottom_cap_standoff_frame_3","size",standoff_frame_3_size); - db->SetDArray("GEO","Bottom_cap_standoff_frame_3","position",standoff_frame_3_pos); - db->SetDArray("GEO","Bottom_cap_standoff_frame_4","size",standoff_frame_4_size); - db->SetDArray("GEO","Bottom_cap_standoff_frame_4","position",standoff_frame_4_pos); + db->Set("GEO","Bottom_cap_standoff_frame_0","size",standoff_frame_0_size); + db->Set("GEO","Bottom_cap_standoff_frame_0","position",standoff_frame_0_pos); + db->Set("GEO","Bottom_cap_standoff_frame_1","size",standoff_frame_1_size); + db->Set("GEO","Bottom_cap_standoff_frame_1","position",standoff_frame_1_pos); + db->Set("GEO","Bottom_cap_standoff_frame_2","size",standoff_frame_2_size); + db->Set("GEO","Bottom_cap_standoff_frame_2","position",standoff_frame_2_pos); + db->Set("GEO","Bottom_cap_standoff_frame_3","size",standoff_frame_3_size); + db->Set("GEO","Bottom_cap_standoff_frame_3","position",standoff_frame_3_pos); + db->Set("GEO","Bottom_cap_standoff_frame_4","size",standoff_frame_4_size); + db->Set("GEO","Bottom_cap_standoff_frame_4","position",standoff_frame_4_pos); info << "Override default PMTINFO information...\n"; - db->SetDArray("PMTINFO","x",x); - db->SetDArray("PMTINFO","y",y); - db->SetDArray("PMTINFO","z",z); - db->SetDArray("PMTINFO","dir_x",dir_x); - db->SetDArray("PMTINFO","dir_y",dir_y); - db->SetDArray("PMTINFO","dir_z",dir_z); - db->SetIArray("PMTINFO","type",type); + db->Set("PMTINFO","x",x); + db->Set("PMTINFO","y",y); + db->Set("PMTINFO","z",z); + db->Set("PMTINFO","dir_x",dir_x); + db->Set("PMTINFO","dir_y",dir_y); + db->Set("PMTINFO","dir_z",dir_z); + db->Set("PMTINFO","type",type); info << "Update geometry fields related to the reflective and absorptive tarps...\n"; info << "Update geometry fields related to veto PMTs...\n"; - db->SetI("GEO","shield","veto_start",num_pmts); - db->SetI("GEO","shield","veto_len",num_vetos); - db->SetI("GEO","veto_pmts","start_idx",num_pmts); - db->SetI("GEO","veto_pmts","end_idx",total_pmts-1); + db->Set("GEO","shield","veto_start",num_pmts); + db->Set("GEO","shield","veto_len",num_vetos); + db->Set("GEO","veto_pmts","start_idx",num_pmts); + db->Set("GEO","veto_pmts","end_idx",total_pmts-1); info << "Update geometry fields related to normal PMTs...\n"; - db->SetI("GEO","shield","cols",cols); - db->SetI("GEO","shield","rows",rows); - db->SetI("GEO","shield","inner_start",0); - db->SetI("GEO","shield","inner_len",num_pmts); - db->SetI("GEO","inner_pmts","start_idx",0); - db->SetI("GEO","inner_pmts","end_idx",num_pmts-1); + db->Set("GEO","shield","cols",cols); + db->Set("GEO","shield","rows",rows); + db->Set("GEO","shield","inner_start",0); + db->Set("GEO","shield","inner_len",num_pmts); + db->Set("GEO","inner_pmts","start_idx",0); + db->Set("GEO","inner_pmts","end_idx",num_pmts-1); info << "Update cable positions to match shield...\n"; - db->SetDArray("cable_pos","x",cable_x); - db->SetDArray("cable_pos","y",cable_y); - db->SetDArray("cable_pos","z",vector(cols,0.0)); - db->SetDArray("cable_pos","dir_x",vector(cols,0.0)); - db->SetDArray("cable_pos","dir_y",vector(cols,0.0)); - db->SetDArray("cable_pos","dir_z",vector(cols,1.0)); + db->Set("cable_pos","x",cable_x); + db->Set("cable_pos","y",cable_y); + db->Set("cable_pos","z",vector(cols,0.0)); + db->Set("cable_pos","dir_x",vector(cols,0.0)); + db->Set("cable_pos","dir_y",vector(cols,0.0)); + db->Set("cable_pos","dir_z",vector(cols,1.0)); //DBLinkPtr inner_pmts = db->GetLink("GEO","inner_pmts"); // const vector &size = table->GetDArray("boxsize"); @@ -412,14 +412,14 @@ namespace RAT { minshift.push_back(-_shift); info << "Update height of rock and cavern air... (" << _shift << " mm shift)\n"; - db->SetDArray("GEO","rock_1", "position",shift); - // db->SetDArray("GEO","cavern", "position",noshift); + db->Set("GEO","rock_1", "position",shift); + // db->Set("GEO","cavern", "position",noshift); info << "Adjust size and position of tank...\n"; - db->SetD("GEO","tank","r_max",detector_size_d/2.0); - db->SetD("GEO","tank","size_z",detector_size_z/2.0); - db->SetDArray("GEO","tank","position",minshift); - // db->SetDArray("GEO","detector","position",minshift); + db->Set("GEO","tank","r_max",detector_size_d/2.0); + db->Set("GEO","tank","size_z",detector_size_z/2.0); + db->Set("GEO","tank","position",minshift); + // db->Set("GEO","detector","position",minshift); } } diff --git a/src/geo/src/WatchmanWLSPSquareDetectorFactory.cc b/src/geo/src/WatchmanWLSPSquareDetectorFactory.cc index 49faa334..bb6801d9 100644 --- a/src/geo/src/WatchmanWLSPSquareDetectorFactory.cc +++ b/src/geo/src/WatchmanWLSPSquareDetectorFactory.cc @@ -239,20 +239,20 @@ namespace RAT { info << "Update geometry fields related to the reflective and absorptive tarps...\n"; // Side tarps - db->SetD("GEO","white_sheet_side","r_max",veto_radius+60.0); - db->SetD("GEO","white_sheet_side","r_min",veto_radius-10.0+60.0); // Marc Bergevin: Hardcoding in a 1 cm value for tickness - db->SetD("GEO","white_sheet_side","size_z",topbot_veto_offset); - db->SetD("GEO","black_sheet_side","r_max",pmt_radius+10.0+60.0); - db->SetD("GEO","black_sheet_side","r_min",pmt_radius+60.0); // Marc Bergevin: Hardcoding in a 1 cm value for tickness - db->SetD("GEO","black_sheet_side","size_z",topbot_offset); + db->Set("GEO","white_sheet_side","r_max",veto_radius+60.0); + db->Set("GEO","white_sheet_side","r_min",veto_radius-10.0+60.0); // Marc Bergevin: Hardcoding in a 1 cm value for tickness + db->Set("GEO","white_sheet_side","size_z",topbot_veto_offset); + db->Set("GEO","black_sheet_side","r_max",pmt_radius+10.0+60.0); + db->Set("GEO","black_sheet_side","r_min",pmt_radius+60.0); // Marc Bergevin: Hardcoding in a 1 cm value for tickness + db->Set("GEO","black_sheet_side","size_z",topbot_offset); - db->SetD("GEO","Rod_assemblies","r_max",(pmt_radius+300.)); // Based on Geofile thickness values of 10 cm - db->SetD("GEO","Rod_assemblies","r_min",(pmt_radius+200.)); - db->SetD("GEO","Rod_assemblies","size_z",topbot_offset); + db->Set("GEO","Rod_assemblies","r_max",(pmt_radius+300.)); // Based on Geofile thickness values of 10 cm + db->Set("GEO","Rod_assemblies","r_min",(pmt_radius+200.)); + db->Set("GEO","Rod_assemblies","size_z",topbot_offset); - db->SetD("GEO","white_sheet_tank_side","r_max",detector_size_d/2.0 -10.0+60.0); - db->SetD("GEO","white_sheet_tank_side","r_min",detector_size_d/2.0 -35.0+60.0); - db->SetD("GEO","white_sheet_tank_side","size_z",detector_size_z/2.0-35.0+60.0); + db->Set("GEO","white_sheet_tank_side","r_max",detector_size_d/2.0 -10.0+60.0); + db->Set("GEO","white_sheet_tank_side","r_min",detector_size_d/2.0 -35.0+60.0); + db->Set("GEO","white_sheet_tank_side","size_z",detector_size_z/2.0-35.0+60.0); //Top tarps @@ -283,18 +283,18 @@ namespace RAT { - db->SetD("GEO","white_sheet_top","r_max",veto_radius); - db->SetDArray("GEO","white_sheet_top","position",move_white_top); - db->SetD("GEO","black_sheet_top","r_max",pmt_radius); - db->SetDArray("GEO","black_sheet_top","position",move_black_top); - db->SetD("GEO","Top_cap_framework","r_max",pmt_radius); - db->SetDArray("GEO","Top_cap_framework","position",move_topcap); - db->SetD("GEO","Wall_support_truss_top","r_min",pmt_radius+5.0); // Bergevin: Values based - db->SetD("GEO","Wall_support_truss_top","r_max",pmt_radius+200.0);// on geofile - db->SetDArray("GEO","Wall_support_truss_top","position",move_toptruss); + db->Set("GEO","white_sheet_top","r_max",veto_radius); + db->Set("GEO","white_sheet_top","position",move_white_top); + db->Set("GEO","black_sheet_top","r_max",pmt_radius); + db->Set("GEO","black_sheet_top","position",move_black_top); + db->Set("GEO","Top_cap_framework","r_max",pmt_radius); + db->Set("GEO","Top_cap_framework","position",move_topcap); + db->Set("GEO","Wall_support_truss_top","r_min",pmt_radius+5.0); // Bergevin: Values based + db->Set("GEO","Wall_support_truss_top","r_max",pmt_radius+200.0);// on geofile + db->Set("GEO","Wall_support_truss_top","position",move_toptruss); - db->SetD("GEO","white_sheet_tank_top","r_max",detector_size_d/2.0 -35.0); - db->SetDArray("GEO","white_sheet_tank_top","position",move_toptanktarp); + db->Set("GEO","white_sheet_tank_top","r_max",detector_size_d/2.0 -35.0); + db->Set("GEO","white_sheet_tank_top","position",move_toptanktarp); @@ -324,18 +324,18 @@ namespace RAT { - db->SetD("GEO","white_sheet_bottom","r_max",veto_radius); - db->SetDArray("GEO","white_sheet_bottom","position",move_white_bottom); - db->SetD("GEO","black_sheet_bottom","r_max",pmt_radius); - db->SetDArray("GEO","black_sheet_bottom","position",move_black_bottom); - db->SetD("GEO","Bottom_cap_framework","r_max",pmt_radius); - db->SetDArray("GEO","Bottom_cap_framework","position",move_bottomcap); - db->SetD("GEO","Wall_support_truss_bottom","r_min",pmt_radius+5.0); // Bergevin: Values based - db->SetD("GEO","Wall_support_truss_bottom","r_max",pmt_radius+200.0);// on geofile - db->SetDArray("GEO","Wall_support_truss_bottom","position",move_bottomtruss); + db->Set("GEO","white_sheet_bottom","r_max",veto_radius); + db->Set("GEO","white_sheet_bottom","position",move_white_bottom); + db->Set("GEO","black_sheet_bottom","r_max",pmt_radius); + db->Set("GEO","black_sheet_bottom","position",move_black_bottom); + db->Set("GEO","Bottom_cap_framework","r_max",pmt_radius); + db->Set("GEO","Bottom_cap_framework","position",move_bottomcap); + db->Set("GEO","Wall_support_truss_bottom","r_min",pmt_radius+5.0); // Bergevin: Values based + db->Set("GEO","Wall_support_truss_bottom","r_max",pmt_radius+200.0);// on geofile + db->Set("GEO","Wall_support_truss_bottom","position",move_bottomtruss); - db->SetD("GEO","white_sheet_tank_bottom","r_max",detector_size_d/2.0 -35.0); - db->SetDArray("GEO","white_sheet_tank_bottom","position",move_bottomtanktarp); + db->Set("GEO","white_sheet_tank_bottom","r_max",detector_size_d/2.0 -35.0); + db->Set("GEO","white_sheet_tank_bottom","position",move_bottomtanktarp); info << "Adjusting the Bottom cap standoff frames ...\n"; @@ -388,82 +388,93 @@ namespace RAT { info << "New size " << standoff_frame_4_size[0] << " " << standoff_frame_4_size[1] << " " << standoff_frame_4_size[2] << "...\n"; } - db->SetDArray("GEO","Bottom_cap_standoff_frame_0","size",standoff_frame_0_size); - db->SetDArray("GEO","Bottom_cap_standoff_frame_0","position",standoff_frame_0_pos); - db->SetDArray("GEO","Bottom_cap_standoff_frame_1","size",standoff_frame_1_size); - db->SetDArray("GEO","Bottom_cap_standoff_frame_1","position",standoff_frame_1_pos); - db->SetDArray("GEO","Bottom_cap_standoff_frame_2","size",standoff_frame_2_size); - db->SetDArray("GEO","Bottom_cap_standoff_frame_2","position",standoff_frame_2_pos); - db->SetDArray("GEO","Bottom_cap_standoff_frame_3","size",standoff_frame_3_size); - db->SetDArray("GEO","Bottom_cap_standoff_frame_3","position",standoff_frame_3_pos); - db->SetDArray("GEO","Bottom_cap_standoff_frame_4","size",standoff_frame_4_size); - db->SetDArray("GEO","Bottom_cap_standoff_frame_4","position",standoff_frame_4_pos); + db->Set("GEO","Bottom_cap_standoff_frame_0","size",standoff_frame_0_size); + db->Set("GEO","Bottom_cap_standoff_frame_0","position",standoff_frame_0_pos); + db->Set("GEO","Bottom_cap_standoff_frame_1","size",standoff_frame_1_size); + db->Set("GEO","Bottom_cap_standoff_frame_1","position",standoff_frame_1_pos); + db->Set("GEO","Bottom_cap_standoff_frame_2","size",standoff_frame_2_size); + db->Set("GEO","Bottom_cap_standoff_frame_2","position",standoff_frame_2_pos); + db->Set("GEO","Bottom_cap_standoff_frame_3","size",standoff_frame_3_size); + db->Set("GEO","Bottom_cap_standoff_frame_3","position",standoff_frame_3_pos); + db->Set("GEO","Bottom_cap_standoff_frame_4","size",standoff_frame_4_size); + db->Set("GEO","Bottom_cap_standoff_frame_4","position",standoff_frame_4_pos); info << "Override default PMTINFO information...\n"; - db->SetDArray("PMTINFO","x",x); - db->SetDArray("PMTINFO","y",y); - db->SetDArray("PMTINFO","z",z); - db->SetDArray("PMTINFO","dir_x",dir_x); - db->SetDArray("PMTINFO","dir_y",dir_y); - db->SetDArray("PMTINFO","dir_z",dir_z); - db->SetIArray("PMTINFO","type",type); + db->Set("PMTINFO","x",x); + db->Set("PMTINFO","y",y); + db->Set("PMTINFO","z",z); + db->Set("PMTINFO","dir_x",dir_x); + db->Set("PMTINFO","dir_y",dir_y); + db->Set("PMTINFO","dir_z",dir_z); + db->Set("PMTINFO","type",type); } info << "Override default WLSPINFO information...\n"; - db->SetDArray("WLSPINFO","x",xp); - db->SetDArray("WLSPINFO","y",yp); - db->SetDArray("WLSPINFO","z",zp); - db->SetDArray("WLSPINFO","dir_x",dir_x); - db->SetDArray("WLSPINFO","dir_y",dir_y); - db->SetDArray("WLSPINFO","dir_z",dir_z); - db->SetIArray("WLSPINFO","type",type); + db->Set("WLSPINFO","x",xp); + db->Set("WLSPINFO","y",yp); + db->Set("WLSPINFO","z",zp); + db->Set("WLSPINFO","dir_x",dir_x); + db->Set("WLSPINFO","dir_y",dir_y); + db->Set("WLSPINFO","dir_z",dir_z); + db->Set("WLSPINFO","type",type); if (photocathode_coverage != 0.00) { info << "Update geometry fields related to the reflective and absorptive tarps...\n"; info << "Update geometry fields related to veto PMTs...\n"; - db->SetI("GEO","shield","veto_start",num_pmts); - db->SetI("GEO","shield","veto_len",num_vetos); - db->SetI("GEO","veto_pmts","start_idx",num_pmts); - db->SetI("GEO","veto_pmts","end_idx",total_pmts-1); + db->Set("GEO","shield","veto_start",num_pmts); + db->Set("GEO","shield","veto_len",num_vetos); + db->Set("GEO","veto_pmts","start_idx",num_pmts); + db->Set("GEO","veto_pmts","end_idx",total_pmts-1); info << "Update geometry fields related to normal PMTs...\n"; - db->SetI("GEO","shield","cols",cols); - db->SetI("GEO","shield","rows",rows); - db->SetI("GEO","shield","inner_start",0); - db->SetI("GEO","shield","inner_len",num_pmts); - db->SetI("GEO","inner_pmts","start_idx",0); - db->SetI("GEO","inner_pmts","end_idx",num_pmts-1); + db->Set("GEO","shield","cols",cols); + db->Set("GEO","shield","rows",rows); + db->Set("GEO","shield","inner_start",0); + db->Set("GEO","shield","inner_len",num_pmts); + db->Set("GEO","inner_pmts","start_idx",0); + db->Set("GEO","inner_pmts","end_idx",num_pmts-1); info << "Update cable positions to match shield...\n"; - db->SetDArray("cable_pos","x",cable_x); - db->SetDArray("cable_pos","y",cable_y); - db->SetDArray("cable_pos","z",vector(cols,0.0)); - db->SetDArray("cable_pos","dir_x",vector(cols,0.0)); - db->SetDArray("cable_pos","dir_y",vector(cols,0.0)); - db->SetDArray("cable_pos","dir_z",vector(cols,1.0)); + db->Set("cable_pos","x",cable_x); + db->Set("cable_pos","y",cable_y); + db->Set("cable_pos","z",vector(cols,0.0)); + db->Set("cable_pos","dir_x",vector(cols,0.0)); + db->Set("cable_pos","dir_y",vector(cols,0.0)); + db->Set("cable_pos","dir_z",vector(cols,1.0)); //This generates the geometry values for the WLS plates and their reflectors - db->SetDArray("GEO","WLS_Plates","size",{(pmt_space/2.0)-10.0,(pmt_space/2.0)-10.0,wlsp->GetDArray("z")[1]}); - db->SetDArray("GEO","WLS_Plates","r_max",{rho_edge[1]+5.0,rho_edge[1]-15.0}); - db->SetDArray("GEO","WLS_Plates","r_min",{0.0,0.0}); - db->SetDArray("GEO","WLS_Plates","z",{-wlsp->GetDArray("z")[1]-1.0,wlsp->GetDArray("z")[1]+1.0}); - db->SetDArray("GEO","WLSP_reflector","inner_size",{(pmt_space/2.0)-10.0,(pmt_space/2.0)-10.0,wlsp->GetDArray("z")[1]+2.0}); - db->SetDArray("GEO","WLSP_reflector","outer_size",{(pmt_space/2.0)-10.0+2.0,(pmt_space/2.0)-10.0+2.0,wlsp->GetDArray("z")[1]}); + db->Set("GEO","WLS_Plates","size", + vector({(pmt_space/2.0)-10.0,(pmt_space/2.0)-10.0,wlsp->GetDArray("z")[1]}) ); + db->Set("GEO","WLS_Plates","r_max", + vector({rho_edge[1]+5.0,rho_edge[1]-15.0})); + db->Set("GEO","WLS_Plates","r_min",vector({0.0,0.0})); + db->Set("GEO","WLS_Plates","z", + vector({-wlsp->GetDArray("z")[1]-1.0,wlsp->GetDArray("z")[1]+1.0})); + db->Set("GEO","WLSP_reflector","inner_size", + vector({(pmt_space/2.0)-10.0,(pmt_space/2.0)-10.0,wlsp->GetDArray("z")[1]+2.0})); + db->Set("GEO","WLSP_reflector","outer_size", + vector({(pmt_space/2.0)-10.0+2.0,(pmt_space/2.0)-10.0+2.0,wlsp->GetDArray("z")[1]})); } else { //If the baseline detector configuration is used, more constant values are used. I still do this here rather than in the geo file because it reads in the PMT dimensions - db->SetDArray("GEO","WLS_Plates","size",{240.0,240.0,wlsp->GetDArray("z")[1]}); - db->SetDArray("GEO","WLS_Plates","r_max",{rho_edge[1]+5.0,rho_edge[1]-15.0}); - db->SetDArray("GEO","WLS_Plates","r_min",{0.0,0.0}); - db->SetDArray("GEO","WLS_Plates","z",{-wlsp->GetDArray("z")[1]-1.0,wlsp->GetDArray("z")[1]+1.0}); - db->SetDArray("GEO","WLSP_reflector","inner_size",{240.0,240.0,wlsp->GetDArray("z")[1]+2.0}); - db->SetDArray("GEO","WLSP_reflector","outer_size",{242.0,242.0,wlsp->GetDArray("z")[1]}); + db->Set("GEO","WLS_Plates","size", + vector({240.0,240.0,wlsp->GetDArray("z")[1]})); + db->Set("GEO","WLS_Plates","r_max", + vector({rho_edge[1]+5.0,rho_edge[1]-15.0})); + db->Set("GEO","WLS_Plates","r_min", + vector({0.0,0.0})); + db->Set("GEO","WLS_Plates","z", + vector({-wlsp->GetDArray("z")[1]-1.0,wlsp->GetDArray("z")[1]+1.0})); + db->Set("GEO","WLSP_reflector","inner_size", + vector({240.0,240.0,wlsp->GetDArray("z")[1]+2.0})); + db->Set("GEO","WLSP_reflector","outer_size", + vector({242.0,242.0,wlsp->GetDArray("z")[1]})); } - //db->SetDArray("GEO","WLSP_reflector","inner_size",{(pmt_space/2.0)-8.0,(pmt_space/2.0)-8.0,wlspcover->GetDArray("z")[1]}); - //db->SetDArray("GEO","WLSP_reflector","outer_size",{(pmt_space/2.0)-9.0,(pmt_space/2.0)-9.0,wlspcover->GetDArray("z")[1]+1}); + //db->Set("GEO","WLSP_reflector","inner_size",{(pmt_space/2.0)-8.0,(pmt_space/2.0)-8.0,wlspcover->GetDArray("z")[1]}); + //db->Set("GEO","WLSP_reflector","outer_size",{(pmt_space/2.0)-9.0,(pmt_space/2.0)-9.0,wlspcover->GetDArray("z")[1]+1}); @@ -488,14 +499,14 @@ namespace RAT { minshift.push_back(-_shift); info << "Update height of rock and cavern air... (" << _shift << " mm shift)\n"; - db->SetDArray("GEO","rock_1", "position",shift); - // db->SetDArray("GEO","cavern", "position",noshift); + db->Set("GEO","rock_1", "position",shift); + // db->Set("GEO","cavern", "position",noshift); info << "Adjust size and position of tank...\n"; - db->SetD("GEO","tank","r_max",detector_size_d/2.0); - db->SetD("GEO","tank","size_z",detector_size_z/2.0); - db->SetDArray("GEO","tank","position",minshift); - // db->SetDArray("GEO","detector","position",minshift); + db->Set("GEO","tank","r_max",detector_size_d/2.0); + db->Set("GEO","tank","size_z",detector_size_z/2.0); + db->Set("GEO","tank","position",minshift); + // db->Set("GEO","detector","position",minshift); } } diff --git a/tools/rat/rat.cc b/tools/rat/rat.cc index e62f8679..9932bfa0 100644 --- a/tools/rat/rat.cc +++ b/tools/rat/rat.cc @@ -102,11 +102,11 @@ int main(int argc, char **argv) { try { // Catch database errors // Set default input and output files if (options.input_filename != "") { - rdb->SetS("IO", "", "default_input_filename", options.input_filename); + rdb->Set("IO", "", "default_input_filename", options.input_filename); info << "Setting default input file to " << options.input_filename << "\n"; } if (options.output_filename != "") { - rdb->SetS("IO", "", "default_output_filename", options.output_filename); + rdb->Set("IO", "", "default_output_filename", options.output_filename); info << "Setting default output file to " << options.output_filename << "\n"; }