Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:17:37

0001 
0002 // Copyright 2021, Jefferson Science Associates, LLC.
0003 // Subject to the terms in the LICENSE file found in the top-level directory.
0004 
0005 
0006 #include "JStringification.h"
0007 
0008 //-------------------------------------------------------------
0009 // GetObjectSummariesAsJSON
0010 //
0011 /// Get objects for the specified factory in the form of
0012 /// JSON formatted strings.
0013 //-------------------------------------------------------------
0014 void JStringification::GetObjectSummariesAsJSON(std::vector<std::string> &json_vec, std::shared_ptr<const JEvent> &jevent, const std::string &object_name, const std::string factory_tag) const{
0015 
0016     // Get object from the given JEvent from the specified factory
0017     std::map<std::string, JObjectSummary> objects;
0018     GetObjectSummaries(objects, jevent, object_name, factory_tag);
0019 
0020     // Loop over objects and create a JSON string out of each
0021     for(auto p : objects){
0022         const std::string &hexaddr = p.first;
0023         JObjectSummary &summary = p.second;
0024         auto str = ObjectToJSON(hexaddr, summary);
0025         json_vec.push_back(str);
0026     }
0027 }
0028 
0029 //-------------------------------------------------------------
0030 // GetObjects
0031 //
0032 /// Get objects for the specified factory in the form of strings
0033 /// organized inside JObjectSummary objects.
0034 //-------------------------------------------------------------
0035 void JStringification::GetObjectSummaries(std::map<std::string, JObjectSummary> &objects, std::shared_ptr<const JEvent> &jevent, const std::string &object_name, const std::string factory_tag) const {
0036 
0037     /// Get objects for the specified factory in the form of strings.
0038 
0039     // bombproof against getting called with no active JEvent
0040     if(jevent.get() == nullptr ) return;
0041     auto fac = jevent->GetFactory(object_name, factory_tag);
0042     if( fac ){
0043         for( auto jobj : fac->GetAs<JObject>()){
0044             JObjectSummary summary;
0045             jobj->Summarize(summary);
0046             std::stringstream ss;
0047             ss << "0x" << std::hex << (uint64_t)jobj << std::dec;
0048             objects[ss.str()] = summary; // key is address of object converted to string
0049         }
0050 #if JANA2_HAVE_ROOT
0051         // For objects inheriting from TObject, we try and convert members automatically
0052         // into JObjectSummary form. This relies on dictionaries being compiled in.
0053         // (see ROOT_GENERATE_DICTIONARY for cmake files).
0054         for( auto tobj : fac->GetAs<TObject>()){
0055             JObjectSummary summary;
0056             auto tclass = TClass::GetClass(tobj->ClassName());
0057             if(tclass){
0058                 auto *members = tclass->GetListOfAllPublicDataMembers();
0059                 for( auto item : *members){
0060                     TDataMember *memitem = dynamic_cast<TDataMember*>(item);
0061                     if( memitem == nullptr ) continue;
0062                     if( memitem->Property() & kIsStatic ) continue; // exclude TObject enums
0063                     JObjectMember jObjectMember;
0064                     jObjectMember.name = memitem->GetName();
0065                     jObjectMember.type = memitem->GetTypeName();
0066                     jObjectMember.value = GetRootObjectMemberAsString(tobj, memitem, jObjectMember.type);
0067                     summary.add(jObjectMember);
0068                 }
0069             }else {
0070                 LOG << "Unable to get TClass for: " << object_name << LOG_END;
0071             }
0072             std::stringstream ss;
0073             ss << "0x" << std::hex << (uint64_t)tobj << std::dec;
0074             objects[ss.str()] = summary; // key is address of object converted to string
0075         }
0076 #endif
0077     }else{
0078         LOG <<"No factory found! object_name=" << object_name << LOG_END;
0079     }
0080 }
0081 
0082 //-------------------------------------------------------------
0083 // ObjectToJSON
0084 //
0085 /// Convert a given JObjectSummary into a JSON formatted string.
0086 /// An additiona "hexaddr" member will be added with the value
0087 /// passed in to this method. This is meant to contain the address
0088 /// of the actual object the JObjectSummary represents.
0089 //-------------------------------------------------------------
0090 std::string JStringification::ObjectToJSON( const std::string &hexaddr, const JObjectSummary &summary ) const {
0091 
0092     std::stringstream ss;
0093     ss << "{\n";
0094     ss << "\"hexaddr\":\"" << hexaddr << "\"\n";
0095     for( auto m : summary.get_fields() ){
0096         ss << ",\"" << m.name << "\":\"" << m.value << "\"\n";
0097     }
0098     ss << "}";
0099 
0100     return ss.str();
0101 }
0102 
0103 //-------------------------------------------------------------
0104 // GetRootObjectMemberAsString
0105 //-------------------------------------------------------------
0106 #if JANA2_HAVE_ROOT
0107 /// GetRootObjectMemberAsString is the entry point for converting members of
0108 /// TObject derived objects into strings. This really only works for a few
0109 /// primitive types, but is useful for debugging/viewing single events.
0110 std::string JStringification::GetRootObjectMemberAsString(const TObject *tobj, const TDataMember *memitem, std::string type) const {
0111     void *addr = (void*)(((uint64_t)tobj) + memitem->GetOffset()); // untyped address of data member
0112 
0113     // Convert char arrays to std:string so they display properly (assume that is what user wants)
0114     std::string tmp;
0115     if( (memitem->Property()&kIsArray) && (type=="char") ){
0116         tmp = (char*)addr;
0117         addr = (void*)&tmp;
0118         type = "string";
0119     }
0120 
0121     if(      type == "int"           ) return GetAddrAsString<int>(addr);
0122     else if( type == "double"        ) return GetAddrAsString<double>(addr);
0123     else if( type == "float"         ) return GetAddrAsString<float>(addr);
0124     else if( type == "char"          ) return GetAddrAsString<char>(addr);
0125     else if( type == "unsigned char" ) return GetAddrAsString<unsigned char>(addr);
0126     else if( type == "unsigned int"  ) return GetAddrAsString<unsigned int>(addr);
0127     else if( type == "long"          ) return GetAddrAsString<long>(addr);
0128     else if( type == "unsigned long" ) return GetAddrAsString<unsigned long>(addr);
0129     else if( type == "ULong64_t"     ) return GetAddrAsString<ULong64_t>(addr);
0130     else if( type == "Long64_t"      ) return GetAddrAsString<Long64_t>(addr);
0131     else if( type == "string"        ) return GetAddrAsString<std::string>(addr);
0132     return "unknown";
0133 }
0134 #endif // JANA2_HAVE_ROOT