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