File indexing completed on 2025-05-12 09:14:01
0001
0002
0003
0004
0005
0006
0007
0008 #include <iostream>
0009 #include <fstream>
0010 using namespace std;
0011
0012 #include "JEventProcessor_janaroot.h"
0013
0014 typedef JEventProcessor_janaroot::TreeInfo TreeInfo;
0015
0016
0017 extern "C"{
0018 void InitPlugin(JApplication *app){
0019 InitJANAPlugin(app);
0020 app->ProvideService(std::make_shared<JLockService>());
0021 app->Add(new JEventProcessor_janaroot());
0022 }
0023 }
0024
0025
0026 static inline void Tokenize(string str, vector<string> &tokens, const char delim=' ')
0027 {
0028 tokens.clear();
0029 unsigned int cutAt;
0030 while( (cutAt = str.find(delim)) != (unsigned int)str.npos ){
0031 if(cutAt > 0)tokens.push_back(str.substr(0,cutAt));
0032 str = str.substr(cutAt+1);
0033 }
0034 if(str.length() > 0)tokens.push_back(str);
0035 }
0036
0037
0038
0039
0040 JEventProcessor_janaroot::JEventProcessor_janaroot()
0041 {
0042 SetTypeName("JEventProcessor_janaroot");
0043
0044
0045
0046
0047 Nmax = 200;
0048
0049
0050 Nevents = 0;
0051
0052
0053 Nwarnings = 0;
0054 MaxWarnings=50;
0055
0056
0057 file = NULL;
0058
0059 }
0060
0061
0062
0063
0064 void JEventProcessor_janaroot::Init(void)
0065 {
0066 JANAROOT_VERBOSE=0;
0067 auto app = GetApplication();
0068 lock_svc = app->GetService<JLockService>();
0069 app->SetDefaultParameter("JANAROOT_VERBOSE", JANAROOT_VERBOSE);
0070
0071 app->SetDefaultParameter("JANAROOT_MAX_OBJECTS", Nmax);
0072 }
0073
0074
0075
0076
0077 void JEventProcessor_janaroot::BeginRun(const std::shared_ptr<const JEvent>& event)
0078 {
0079 auto app = GetApplication();
0080
0081
0082 lock_svc->RootWriteLock();
0083
0084
0085 string factories_to_write_out="";
0086 app->SetDefaultParameter("WRITEOUT", factories_to_write_out);
0087
0088 if(factories_to_write_out!=""){
0089
0090 size_t pos=0;
0091 string &str = factories_to_write_out;
0092 while( (pos = str.find(",")) != string::npos ){
0093 if(pos > 0){
0094 nametags_to_write_out.push_back(str.substr(0,pos));
0095 }
0096 str = str.substr(pos+1);
0097 }
0098 if(str.length() > 0){
0099 nametags_to_write_out.push_back(str);
0100 }
0101
0102
0103
0104 for(unsigned int j=0; j<nametags_to_write_out.size(); j++){
0105
0106
0107 stringstream ss;
0108 ss<<nametags_to_write_out[j];
0109 ss>>nametags_to_write_out[j];
0110
0111
0112
0113
0114 if(nametags_to_write_out[j].size()<1)continue;
0115 size_t pos_last = nametags_to_write_out[j].size()-1;
0116 if(nametags_to_write_out[j][pos_last] == ':'){
0117 nametags_to_write_out[j].erase(pos_last);
0118 }
0119 }
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129 jout<<"Factories whose objects will be written to ROOT file:"<<endl;
0130
0131
0132 for (auto factory : event->GetFactorySet()->GetAllFactories()) {
0133 auto nametag = factory->GetObjectName();
0134 auto tag = factory->GetTag();
0135
0136 if (!tag.empty()) nametag += ":" + tag;
0137
0138
0139 for(unsigned int j=0; j<nametags_to_write_out.size(); j++){
0140 if(nametags_to_write_out[j] == nametag){
0141 jout<<" "<<nametag<<endl;
0142 }
0143 }
0144 }
0145 }
0146
0147 lock_svc->RootUnLock();
0148 }
0149
0150
0151
0152
0153 void JEventProcessor_janaroot::Process(const std::shared_ptr<const JEvent>& event)
0154 {
0155
0156
0157
0158
0159
0160
0161
0162 lock_svc->RootWriteLock();
0163
0164
0165 if( !file ){
0166
0167
0168
0169 TDirectory *cwd = gDirectory;
0170
0171
0172 file = new TFile("janaroot.root","RECREATE");
0173
0174
0175 cwd->cd();
0176 }
0177
0178
0179 vector<JFactory*> allfactories = event->GetFactorySet()->GetAllFactories();
0180 vector<JFactory*> facs;
0181 for(unsigned int i=0; i<allfactories.size(); i++){
0182
0183
0184
0185
0186
0187
0188 if(nametags_to_write_out.size()>0){
0189 allfactories[i]->ClearFactoryFlag(JFactory::WRITE_TO_OUTPUT);
0190
0191 string nametag = allfactories[i]->GetObjectName();
0192 string tag = allfactories[i]->GetTag();
0193 if(!tag.empty()) nametag += ":" + tag;
0194 for(unsigned int j=0; j<nametags_to_write_out.size(); j++){
0195 if(nametags_to_write_out[j] == nametag){
0196 allfactories[i]->SetFactoryFlag(JFactory::WRITE_TO_OUTPUT);
0197 }
0198 }
0199 }
0200
0201 if(allfactories[i]->TestFactoryFlag(JFactory::WRITE_TO_OUTPUT)) facs.push_back(allfactories[i]);
0202 }
0203
0204
0205 map<std::string, TreeInfo*>::iterator iter=trees.begin();
0206 for(; iter!=trees.end(); iter++)*(iter->second->Nptr) = 0;
0207
0208
0209 for(unsigned int i=0; i<facs.size(); i++){
0210
0211
0212
0213
0214 TreeInfo *tinfo = GetTreeInfo(facs[i]);
0215 if(!tinfo)continue;
0216
0217 FillTree(facs[i], tinfo);
0218 }
0219
0220
0221 for(iter=trees.begin(); iter!=trees.end(); iter++)iter->second->tree->Fill();
0222
0223 Nevents++;
0224
0225
0226 lock_svc->RootUnLock();
0227 }
0228
0229
0230
0231
0232 void JEventProcessor_janaroot::EndRun(void)
0233 {
0234
0235 }
0236
0237
0238
0239
0240 void JEventProcessor_janaroot::Finish(void)
0241 {
0242 lock_svc->RootWriteLock();
0243 if(!file){
0244 lock_svc->RootUnLock();
0245 }
0246
0247
0248 TDirectory *cwd = gDirectory;
0249 file->cd();
0250
0251
0252
0253
0254 TTree *event = new TTree("event","All objects");
0255 map<std::string, TreeInfo*>::iterator iter;
0256 for(iter=trees.begin(); iter!=trees.end(); iter++){
0257 event->AddFriend(iter->second->tree->GetName());
0258 }
0259
0260
0261 cwd->cd();
0262
0263
0264 file->Write();
0265 delete file;
0266 file=NULL;
0267
0268 lock_svc->RootUnLock();
0269 }
0270
0271
0272
0273
0274 TreeInfo* JEventProcessor_janaroot::GetTreeInfo(JFactory *fac)
0275 {
0276
0277
0278
0279 string key = string(fac->GetObjectName())+":"+fac->GetTag();
0280 map<string, TreeInfo*>::iterator iter = trees.find(key);
0281 if(iter!=trees.end())return iter->second;
0282
0283
0284
0285 auto objs = fac->GetAs<JObject>();
0286 vector<vector<JObjectMember>> items;
0287 for (auto obj:objs) {
0288 JObjectSummary obj_sum;
0289 obj->Summarize(obj_sum);
0290 std::vector<JObjectMember> obj_fields = obj_sum.get_fields();
0291 items.push_back(obj_fields);
0292 }
0293
0294
0295
0296
0297
0298 if(items.size()==0)return NULL;
0299
0300
0301 TreeInfo *tinfo = new TreeInfo;
0302
0303
0304 TDirectory *cwd = gDirectory;
0305 file->cd();
0306
0307
0308 string tname = fac->GetObjectName();
0309 if(fac->GetTag().size()>0)tname += string("_") + fac->GetTag();
0310 tinfo->tree = new TTree(tname.c_str(),"Autogenerated from JANA objects");
0311
0312
0313 cwd->cd();
0314
0315
0316 tinfo->branches.push_back(tinfo->tree->Branch("N" , (void*)NULL, "N/I"));
0317
0318
0319 tinfo->obj_size=0;
0320 for(unsigned int i=0; i<items[0].size(); i++){
0321
0322
0323 auto field_name = items[0][i].name;
0324 unsigned int cutAt = field_name.find('(');
0325 string iname = (cutAt==(unsigned int)field_name.npos) ? field_name:field_name.substr(0,cutAt);
0326
0327
0328
0329 for(size_t k=0; k<iname.size(); k++){
0330 if(iname[k]==' ')iname[k] = '_';
0331 if(iname[k]=='.')iname[k] = '_';
0332 }
0333
0334 unsigned long item_size=0;
0335 data_type_t type = type_unknown;
0336 auto field_type = items[0][i].type;
0337 string branch_def;
0338 if(field_type=="int"){
0339 branch_def = iname + "[N]/I";
0340 item_size = sizeof(int);
0341 type = type_int;
0342 }else if(field_type=="uint"){
0343 branch_def = iname + "[N]/i";
0344 item_size = sizeof(unsigned int);
0345 type = type_uint;
0346 }else if(field_type=="long"){
0347 branch_def = iname + "[N]/L";
0348 item_size = sizeof(long);
0349 type = type_long;
0350 }else if(field_type=="ulong"){
0351 branch_def = iname + "[N]/l";
0352 item_size = sizeof(unsigned long);
0353 type = type_ulong;
0354 }else if(field_type=="short"){
0355 branch_def = iname + "[N]/S";
0356 item_size = sizeof(short);
0357 type = type_short;
0358 }else if(field_type=="ushort"){
0359 branch_def = iname + "[N]/s";
0360 item_size = sizeof(unsigned short);
0361 type = type_ushort;
0362 }else if(field_type=="float"){
0363 branch_def = iname + "[N]/F";
0364 item_size = sizeof(float);
0365 type = type_float;
0366 }else if(field_type=="double"){
0367 branch_def = iname + "[N]/D";
0368 item_size = sizeof(double);
0369 type = type_double;
0370 }else if(field_type=="string"){
0371
0372 tinfo->StringMap[i];
0373 item_size = 0;
0374 type = type_string;
0375 }else{
0376 branch_def = iname + "[N]/F";
0377 item_size = sizeof(float);
0378 type = type_unknown;
0379 }
0380
0381
0382 tinfo->types.push_back(type);
0383 tinfo->item_sizes.push_back(item_size);
0384 tinfo->obj_size += item_size;
0385
0386
0387 TBranch *branch = NULL;
0388 if(type == type_string){
0389 branch = tinfo->tree->Branch(iname.c_str(), &tinfo->StringMap[i]);
0390 }else{
0391 branch = tinfo->tree->Branch(iname.c_str(), (void*)NULL, branch_def.c_str());
0392 }
0393 tinfo->branches.push_back(branch);
0394 }
0395
0396
0397 if(tinfo->item_sizes.size()<1){
0398 _DBG_<<"No usable data members in \""<<tname<<"\"!"<<endl;
0399 }
0400
0401
0402 tinfo->Nmax = Nmax;
0403 tinfo->buff_size = sizeof(int) + tinfo->Nmax*tinfo->obj_size;
0404 tinfo->buff = new char[tinfo->buff_size];
0405 tinfo->Nptr = (int*)tinfo->buff;
0406 tinfo->Bptr = (unsigned long)&tinfo->Nptr[1];
0407
0408
0409 trees[key] = tinfo;
0410
0411
0412
0413
0414 *tinfo->Nptr = 0;
0415 for(unsigned long i=0; i<Nevents; i++)tinfo->tree->Fill();
0416
0417 if(JANAROOT_VERBOSE>0)tinfo->Print();
0418
0419 return tinfo;
0420 }
0421
0422
0423
0424
0425 void JEventProcessor_janaroot::FillTree(JFactory *fac, TreeInfo *tinfo)
0426 {
0427
0428
0429
0430 auto objs = fac->GetAs<JObject>();
0431 vector<vector<JObjectMember>> items;
0432 for (auto obj:objs) {
0433 JObjectSummary obj_sum;
0434 obj->Summarize(obj_sum);
0435 std::vector<JObjectMember> obj_fields = obj_sum.get_fields();
0436 items.push_back(obj_fields);
0437 }
0438
0439
0440 unsigned int Nitems = tinfo->types.size();
0441 for(unsigned int i=0; i<items.size(); i++){
0442 if(items[i].size()!=Nitems){
0443 _DBG_<<"Number of items inconsistent for Tree "<<tinfo->tree->GetName()
0444 <<" Nitems="<<Nitems<<" items["<<i<<"].size()="<<items[i].size()<<endl;
0445 return;
0446 }
0447 }
0448
0449
0450 *tinfo->Nptr = (int)items.size()<tinfo->Nmax ? (int)items.size():tinfo->Nmax;
0451
0452
0453 vector<string> tokens;
0454 unsigned long ptr = tinfo->Bptr;
0455 for(unsigned int j=0; j<tinfo->types.size(); j++){
0456
0457 if(tinfo->branches[j+1] == NULL)continue;
0458
0459
0460 if(tinfo->types[j] == type_string){
0461
0462
0463 tinfo->StringMap[j].clear();
0464 }else{
0465 tinfo->branches[j+1]->SetAddress((void*)ptr);
0466 }
0467
0468
0469 for(unsigned int i=0; i<(unsigned int)*tinfo->Nptr; i++){
0470
0471 stringstream ss(items[i][j].value);
0472 string str;
0473
0474 switch(tinfo->types[j]){
0475 case type_short:
0476 ss>>(*(short*)ptr);
0477 break;
0478 case type_ushort:
0479 ss>>(*(unsigned short*)ptr);
0480 break;
0481 case type_int:
0482 ss>>(*(int*)ptr);
0483 break;
0484 case type_uint:
0485 ss>>(*(unsigned int*)ptr);
0486 break;
0487 case type_long:
0488 ss>>(*(long*)ptr);
0489 break;
0490 case type_ulong:
0491 ss>>(*(unsigned long*)ptr);
0492 break;
0493 case type_float:
0494 ss>>(*(float*)ptr);
0495 break;
0496 case type_double:
0497 ss>>(*(double*)ptr);
0498 break;
0499 case type_string:
0500 str = items[i][j].value;
0501
0502 tinfo->StringMap[j].push_back(str);
0503 break;
0504 default:
0505 if(Nwarnings<MaxWarnings && JANAROOT_VERBOSE>0){
0506 _DBG_<<"Unknown type: "<<tinfo->types[j];
0507 Nwarnings++;
0508 if(Nwarnings==MaxWarnings)cerr<<" --last warning! --";
0509 cerr<<endl;
0510 }
0511 break;
0512 }
0513 ptr += tinfo->item_sizes[j];
0514 }
0515 }
0516
0517
0518 tinfo->branches[0]->SetAddress((void*)tinfo->Nptr);
0519 }
0520