// a simple test for measure the speed of the reading a tag file #include #include #include #include #include #include #include #include #include #include class tagValues { public: enum DATA_TYPE {RID=0, FID, INT, UINT, FLOAT, DOUBLE, KEY, STRING}; DATA_TYPE type; tagValues(DATA_TYPE t) : type(t) {} virtual ~tagValues() {}; }; class tagInt : public tagValues { public: std::vector value; tagInt() : tagValues(INT) {}; virtual ~tagInt() {}; }; class tagUInt : public tagValues { public: std::vector value; tagUInt() : tagValues(UINT) {}; virtual ~tagUInt() {}; }; class tagFloat : public tagValues { public: std::vector value; tagFloat() : tagValues(FLOAT) {}; virtual ~tagFloat() {}; }; class tagDouble : public tagValues { public: std::vector value; tagDouble() : tagValues(DOUBLE) {}; virtual ~tagDouble() {}; }; // push strings together into null-terminated list of char class tagString : public tagValues { public: std::vector value; tagString() : tagValues(STRING) {}; virtual ~tagString() {}; }; typedef std::map tagStore; // returns the number of events read long read(const char* tagsfile) { long cnt = 0; TFile tf(tagsfile); TTree *tt = reinterpret_cast(tf.Get("Tag")); if (tt == 0) return cnt; unsigned nerr = 0; // number of errors encountered during read const unsigned nent = tt->GetEntries(); // number of entries in the file if (nent < 5) { // very likely something is wrong printf("tag file \"%s\" is very likely to be a " "bad fie, it contains %u entr%s\n", tagsfile, nent, (nent>1 ? "ies" : "y")); return cnt; } else printf("tag file \"%s\" contains %u entries\n", tagsfile, nent); tagStore store; TObjArray *leaves = tt->GetListOfLeaves(); unsigned nLeaves = leaves->GetEntriesFast(); if (nLeaves < 5) { fprintf(stderr, "tag file \"%s\" is very likely to be a " "bad fie, it contains %u lea%s\n", tagsfile, nLeaves, (nLeaves>1 ? "ves" : "f")); return cnt; } for (unsigned ilv=0; ilv < nLeaves; ++ ilv) { // for each leaf TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(ilv); unsigned ndim = leaf->GetNdata(); tagValues *tval = 0; const char *lname = leaf->GetName(); const char *tmp = strrchr(lname, '.'); if (tmp) // we only use the portion of the name after the last '.' lname = tmp + 1; switch (leaf->GetTypeName()[0]) { case 'C': // null-terminated string { // a null-terminated string has at most ndim characters tagString *act = new tagString; act->value.reserve(nent*ndim); for (unsigned i = 0; i < nent; ++ i) { TBranch *br = leaf->GetBranch(); br->GetEntry(i); tmp = (const char*)leaf->GetValuePointer(); while (*tmp != 0) { // not the terminator act->value.push_back(*tmp); ++ tmp; } // record the terminator act->value.push_back(static_cast(0)); } tval = act; } break; case 'B': // signed 8-bit integer { tagInt *act = new tagInt; act->value.reserve(nent*ndim); for (unsigned i = 0; i < nent; ++ i) { TBranch *br = leaf->GetBranch(); br->GetEntry(i); const char *ptr = ((char*)leaf->GetValuePointer()); if (ndim > 2) { for (unsigned j = 0; j < ndim; ++ j) act->value.push_back(ptr[j]); } else if (ndim == 2) { act->value.push_back(*ptr); act->value.push_back(ptr[1]); } else { act->value.push_back(*ptr); } } tval = act; } break; case 'S': // signed 16-bit integer { tagInt *act = new tagInt; act->value.reserve(nent*ndim); for (unsigned i = 0; i < nent; ++ i) { TBranch *br = leaf->GetBranch(); br->GetEntry(i); short* ptr = (short*)leaf->GetValuePointer(); if (ndim > 2) { for (unsigned j = 0; j < ndim; ++ j) act->value.push_back(ptr[j]); } else if (ndim == 2) { act->value.push_back(*ptr); act->value.push_back(ptr[1]); } else { act->value.push_back(*ptr); } } tval = act; } break; case 'I': // signed 32-bit integer { tagInt *act = new tagInt; act->value.reserve(nent*ndim); for (unsigned i = 0; i < nent; ++ i) { TBranch *br = leaf->GetBranch(); br->GetEntry(i); int* ptr = (int*)leaf->GetValuePointer(); if (ndim > 2) { for (unsigned j = 0; j < ndim; ++ j) act->value.push_back(ptr[j]); } else if (ndim == 2) { act->value.push_back(*ptr); act->value.push_back(ptr[1]); } else { act->value.push_back(*ptr); } } tval = act; } break; case 'b': // unsigned 8-bit integer { tagUInt *act = new tagUInt; act->value.reserve(nent*ndim); for (unsigned i = 0; i < nent; ++ i) { TBranch *br = leaf->GetBranch(); br->GetEntry(i); char* ptr = (char*)leaf->GetValuePointer(); if (ndim > 2) { for (unsigned j = 0; j < ndim; ++ j) act->value.push_back(ptr[j]); } else if (ndim == 2) { act->value.push_back(*ptr); act->value.push_back(ptr[1]); } else { act->value.push_back(*ptr); } } tval = act; } break; case 's': // unsigned 16-bit integer { tagUInt *act = new tagUInt; act->value.reserve(nent*ndim); for (unsigned i = 0; i < nent; ++ i) { TBranch *br = leaf->GetBranch(); br->GetEntry(i); unsigned short *ptr = (unsigned short*)leaf->GetValuePointer(); if (ndim > 2) { for (unsigned j = 0; j < ndim; ++ j) act->value.push_back(ptr[j]); } else if (ndim == 2) { act->value.push_back(*ptr); act->value.push_back(ptr[1]); } else { act->value.push_back(*ptr); } } tval = act; } break; case 'i': // unsigned 32-bit integer { tagUInt *act = new tagUInt; act->value.reserve(nent*ndim); for (unsigned i = 0; i < nent; ++ i) { TBranch *br = leaf->GetBranch(); br->GetEntry(i); unsigned int *ptr = (unsigned int*)leaf->GetValuePointer(); if (ndim > 2) { for (unsigned j = 0; j < ndim; ++ j) act->value.push_back(ptr[j]); } else if (ndim == 2) { act->value.push_back(*ptr); act->value.push_back(ptr[1]); } else { act->value.push_back(*ptr); } } tval = act; } break; case 'F': // 32-bit floating point number { tagFloat *act = new tagFloat; act->value.reserve(nent*ndim); for (unsigned i = 0; i < nent; ++ i) { TBranch *br = leaf->GetBranch(); br->GetEntry(i); float *ptr = (float*)leaf->GetValuePointer(); if (ndim > 2) { for (unsigned j = 0; j < ndim; ++ j) act->value.push_back(ptr[j]); } else if (ndim == 2) { act->value.push_back(*ptr); act->value.push_back(ptr[1]); } else { act->value.push_back(*ptr); } } tval = act; } break; case 'D': // 64-bit floating point number { tagDouble *act = new tagDouble; act->value.reserve(nent*ndim); for (unsigned i = 0; i < nent; ++ i) { TBranch *br = leaf->GetBranch(); br->GetEntry(i); double *ptr = (double*)leaf->GetValuePointer(); if (ndim > 2) { for (unsigned j = 0; j < ndim; ++ j) act->value.push_back(ptr[j]); } else if (ndim == 2) { act->value.push_back(*ptr); act->value.push_back(ptr[1]); } else { act->value.push_back(*ptr); } } tval = act; } break; default: fprintf(stderr, "tag file \"%s\" contains unknown " "data type %s for leaf %s:%s\n", tagsfile, leaf->GetTypeName(), leaf->GetName(), leaf->GetTitle()); ++ nerr; break; } if (tval) { store[lname] = tval; } else { fprintf(stderr, "unable to read \"%s:%s\"\n", lname, leaf->GetTypeName()); ++ nerr; } } // for (unsigned ilv=0 tf.Close(); // no longer need to have it open if (nerr != 0) { fprintf(stderr, "accumulated %u error%s while reading " "\"%s\", will not write out to disk\n", nerr, (nerr > 1 ? "s" : ""), tagsfile); } return cnt; } // read int main(int argc, char **argv) { for (int i = 1; i < argc; ++ i) { printf("\n%s: read(%s) ...\n", *argv, argv[i]); read(argv[i]); } return 0; } // main