00001
00002
00003
00004
00005
00006
00007
00009
00010 #ifndef _ALEPHNTUPLEWRITER_H_
00011 #define _ALEPHNTUPLEWRITER_H_
00012
00013 #include "AlephCardsReader.h"
00014 #include <cfortran.h>
00015 #include "hbook.h"
00016 #include "SmartPointer.h"
00017
00018 #include "TFile.h"
00019 #include "TTree.h"
00020 #include "TNtuple.h"
00021
00022 #include "UserClasses.h"
00023 #include <typeinfo>
00024 #include <string>
00025 #include <vector>
00026 #include <map>
00027 #include <stdarg.h>
00028
00029 #include "CLHEP/Vector/LorentzVector.h"
00030 #include "CLHEP/Vector/ThreeVector.h"
00031
00033
00037 class AlephNtupleWriter {
00038 public:
00040 AlephNtupleWriter();
00041
00043 virtual ~AlephNtupleWriter();
00044
00046 virtual void Initialize(AlephCardsReader*, int) ;
00047
00049 template<typename tpe> void AddOutput(tpe obj, char* name)
00050 {
00051 string clss;
00052 if (typeid(obj)==typeid(int)) clss = "I";
00053 else if (typeid(obj)==typeid(unsigned int)) clss = "i";
00054 else if (typeid(obj)==typeid(float)) clss = "F";
00055 else if (typeid(obj)==typeid(double)) clss = "D";
00056 else if (typeid(obj)==typeid(short)) clss = "B";
00057 else if (typeid(obj)==typeid(unsigned short)) clss = "b";
00058 else if (typeid(obj)==typeid(long)) clss = "I";
00059 else if (typeid(obj)==typeid(unsigned long)) clss = "i";
00060 else clss = typeid(obj).name()+strspn(typeid(obj).name(),"0123456789");
00061 switch (type)
00062 {
00063 case 1 :
00064 {
00065 smart_type<tpe>* theObject = new smart_type<tpe>;
00066 theObjects.push_back(theObject);
00067 void* address = theObject->theaddr();
00068 void* ptr = theObject->theptr();
00069 NamesIndexes[name] = (theObjects.size()-1);
00070 if ((strlen(clss.c_str())==1)&&(strpbrk(clss.c_str(),"CBbSsIiFD")!=(char*)NULL))
00071 {
00072 string arg3 = string(name)+string("/")+string(clss);
00073 ROOTtree->Branch(name,address,arg3.c_str());
00074 }
00075 else
00076 {
00077 ROOTtree->Branch(name,clss.c_str(),ptr);
00078 }
00079 }
00080 break;
00081 case 2 :
00082 if ((strlen(clss.c_str())==1)&&(strpbrk(clss.c_str(),"CBbSsIiFD")!=(char*)NULL))
00083 {
00084 size++;
00085 char procname[8];
00086 strncpy(procname,name,7);
00087 for(int i=strlen(name);i<7;i++)
00088 procname[i]=' ';
00089 procname[7] = 0;
00090 NamesIndexes[procname] = size-1;
00091 data.push_back(0.);
00092 }
00093 else
00094 cerr << "ERROR: type " << name << " not supported by HBOOKwriter." << endl;
00095 break;
00096 default :
00097 cerr << "ERROR: Bad Ntuple Type." << endl;
00098 exit(0);
00099 }
00100 }
00102 template<typename tpe> void AddOutput(tpe obj, unsigned int sze, ...)
00103 {
00104 va_list ap;
00105 va_start(ap,sze);
00106 for(unsigned int arg=0;arg<sze;arg++)
00107 {
00108 char *name = va_arg(ap,char*);
00109 string clss;
00110 if (typeid(obj)==typeid(int)) clss = "I";
00111 else if (typeid(obj)==typeid(unsigned int)) clss = "i";
00112 else if (typeid(obj)==typeid(float)) clss = "F";
00113 else if (typeid(obj)==typeid(double)) clss = "D";
00114 else if (typeid(obj)==typeid(short)) clss = "B";
00115 else if (typeid(obj)==typeid(unsigned short)) clss = "b";
00116 else if (typeid(obj)==typeid(long)) clss = "I";
00117 else if (typeid(obj)==typeid(unsigned long)) clss = "i";
00118 else clss = typeid(obj).name()+strspn(typeid(obj).name(),"0123456789");
00119 switch (type)
00120 {
00121 case 1 :
00122 {
00123 smart_type<tpe>* theObject = new smart_type<tpe>;
00124 theObjects.push_back(theObject);
00125 void* address = theObject->theaddr();
00126 void* ptr = theObject->theptr();
00127 NamesIndexes[name] = (theObjects.size()-1);
00128 if ((strlen(clss.c_str())==1)&&(strpbrk(clss.c_str(),"CBbSsIiFD")!=(char*)NULL))
00129 {
00130 string arg3 = string(name)+string("/")+string(clss);
00131 ROOTtree->Branch(name,address,arg3.c_str());
00132 }
00133 else
00134 {
00135 ROOTtree->Branch(name,clss.c_str(),ptr);
00136 }
00137 }
00138 break;
00139 case 2 :
00140 if ((strlen(clss.c_str())==1)&&(strpbrk(clss.c_str(),"CBbSsIiFD")!=(char*)NULL))
00141 {
00142 size++;
00143 char procname[8];
00144 strncpy(procname,name,7);
00145 for(int i=strlen(name);i<7;i++)
00146 procname[i]=' ';
00147 procname[7] = 0;
00148 NamesIndexes[procname] = size-1;
00149 data.push_back(0.);
00150 }
00151 else
00152 cerr << "ERROR: type " << name << " not supported by HBOOKwriter." << endl;
00153 break;
00154 default :
00155 cerr << "ERROR: Bad Ntuple Type." << endl;
00156 exit(0);
00157 }
00158 }
00159 va_end(ap);
00160 }
00161
00163 template<typename tpe> void AddScalableOutput(char* name, tpe obj, unsigned int size)
00164 {
00165 string clss;
00166 if (typeid(obj)==typeid(int)) clss = "I";
00167 else if (typeid(obj)==typeid(unsigned int)) clss = "i";
00168 else if (typeid(obj)==typeid(float)) clss = "F";
00169 else if (typeid(obj)==typeid(double)) clss = "D";
00170 else if (typeid(obj)==typeid(short)) clss = "B";
00171 else if (typeid(obj)==typeid(unsigned short)) clss = "b";
00172 else if (typeid(obj)==typeid(long)) clss = "I";
00173 else if (typeid(obj)==typeid(unsigned long)) clss = "i";
00174 else
00175 {
00176 cerr << "ERROR: cannot create an array of non-elementary type" << endl;
00177 return;
00178 }
00179 switch (type)
00180 {
00181 case 1 :
00182 {
00183 smart_type<tpe>* theObject = new smart_type<tpe>(size);
00184 theObjects.push_back(theObject);
00185 void* address = theObject->theaddr();
00186 NamesIndexes[name] = (theObjects.size()-1);
00187
00188 string nname = string("n")+string(name);
00189 string arg3 = nname + string("/I");
00190 ROOTtree->Branch(nname.c_str(),SizeAddresses[name] = new int,arg3.c_str());
00191 arg3 = string(name)+string("[")+nname+string("]/")+string(clss);
00192 ROOTtree->Branch(name,address,arg3.c_str());
00193 }
00194 break;
00195 case 2 :
00196 cerr << "ERROR: column-wise ntuple still not handled... AddScalableOutput unavailable." << endl;
00197 break;
00198 default :
00199 cerr << "ERROR: Bad Ntuple Type." << endl;
00200 exit(0);
00201 }
00202 }
00203
00205 virtual void Fill();
00206
00208 virtual void Terminate();
00209
00211 template <typename entry> void Keep(const char* name , const entry* value , const int size)
00212 {
00213 switch(type)
00214 {
00215 case 1 :
00216 {
00217 *((*SizeAddresses.find(name)).second) = size;
00218 entry* array = (entry*)theObjects[NamesIndexes.find(name)->second]->theaddr();
00219 for(int i=0;i<size;i++) array[i] = value[i];
00220 }
00221 break;
00222 case 2 :
00223 cerr << "ERROR: column-wise ntuple still not handled... Keep(char*, entry*, int) unavailable." << endl;
00224 break;
00225 default:
00226 cerr << "ERROR: Bad Ntuple Type." << endl;
00227 exit(0);
00228 }
00229 }
00230
00232 template <typename entry> void KeepV(const char* name , vector<entry> value)
00233 {
00234 unsigned int size = value.size();
00235 switch(type)
00236 {
00237 case 1 :
00238 {
00239 *((*SizeAddresses.find(name)).second) = size;
00240 entry* array = (entry*)theObjects[NamesIndexes.find(name)->second]->theaddr();
00241 for(unsigned int i=0;i<size;i++) array[i] = value[i];
00242 }
00243 break;
00244 case 2 :
00245 cerr << "ERROR: column-wise ntuple still not handled... Keep(char*, entry*, int) unavailable." << endl;
00246 break;
00247 default:
00248 cerr << "ERROR: Bad Ntuple Type." << endl;
00249 exit(0);
00250 }
00251 }
00252
00254 template <typename entry> void Keep(const char* name, const entry& value)
00255 {
00256 switch(type)
00257 {
00258 case 1 :
00259 *(entry*)theObjects[NamesIndexes.find(name)->second]->theaddr() = value;
00260 break;
00261 case 2 :
00262 char procname[8];
00263 strncpy(procname,name,7);
00264 for(int i=strlen(name);i<7;i++)
00265 procname[i]=' ';
00266 procname[7] = 0;
00267 data[ NamesIndexes.find(procname)->second ] = (float)value;
00268 break;
00269 default:
00270 cerr << "ERROR: Bad Ntuple Type." << endl;
00271 exit(0);
00272 }
00273 }
00274
00276 void Keep(const char* name, const HepLorentzVector& value)
00277 {
00278 float tmp[4];
00279 tmp[0] = value[0]; tmp[1] = value[1]; tmp[2] = value[2]; tmp[3] = value[3];
00280 Keep(name, tmp, 4);
00281 }
00282
00283
00285 void Keep(const char* name, const Hep3Vector& value)
00286 {
00287 float tmp[3];
00288 tmp[0] = value[0]; tmp[1] = value[1]; tmp[2] = value[2];
00289 Keep(name, tmp, 3);
00290 }
00291
00292
00293 private:
00294
00295 int type;
00296 AlephCardsReader* cards;
00297 map<string,int> NamesIndexes;
00298
00299
00300 int size;
00301 vector<float> data;
00302 bool booked;
00303
00304
00305 TFile* ROOTfile;
00306 TTree* ROOTtree;
00307 map<string,int*> SizeAddresses;
00308 vector<smart_void*> theObjects;
00309
00310 };
00311
00312 #endif
00313