void treetest(int nmax = 100000){ // macro to test 3 methods to write a time series to a root file. // Tree 1 has a branch for EACH BYTE of struct ts (i.e. 20 branches). // Tree 2 has one branch for each Int_t word of ts (i.e. 5 branches). // Tree 3 has one branch for the whole ts struct only. // // NOTE: the idea (hope) for tree 1 is that time series often // fluctuate around some mean values (e.g. zero in the white noise // case below) and the high bytes are mostly zero since outliers // happen rarely. Those bytes should be highly compressible! // This is extremely true for time series recorded from neuronal firing // patters; those flucutate mostly around zero (with noise) // and produce a spike only every 10-1000 msec. // // Results: tree 1 compresses by a factor 4.6 & produces mmzip error messages // tree 2 factor 2 (no mmzip errors) // tree 3 factor 1.75 (no mmzip errors) struct{ Int_t t; // time stamps Int_t w[4]; // waveform data } ts; // time series data point // use a union inside a struct for accessing the bytes of tmpT.l,tmpW[].l struct{ union { char c[4]; long l; }; } tmpT, tmpW[4]; struct{ Char_t c; } ch[20]; // struct for accessing the bytes of ts directly // OUT file TFile f1("treetest.root","RECREATE","Test of root trees"); f1.SetCompressionLevel(0); // tree with 20 branches; one for each byte of tmpT, tmpW[4] TTree *t1 = new TTree("T1"," Compressed bytes"); Int_t bufsz = 16000; // tried 8000, ...,64000 - still get mmzip errors // with bufsz=128000, get no mmzip errors, but // but also NO obvious compression measured by // actual .root file size! char* index = " "; TString bbase = "c"; // branch name base TString bname, leafname; for(Int_t j=0; j<20; j++){ sprintf(index,"%d",j); // make j to zstring bname = bbase + index; // append index to bname base leafname = bname + "/B1"; // append leaftype+size t1->Branch(bname.Data(),&ch[j],leafname.Data(),bufsz); } // tree with 5 branches; one for each tmpT, tmpW[4] struct TTree *t2 = new TTree("T2"," Compressed structs tmpT, tmpW[4]"); bufsz = 32000; bbase = "l"; for(j=0; j<4; j++){ sprintf(index,"%d",j); // make j to zstring bname = bbase + index; // append index to bname base leafname = bname + "/I"; // append leaftype+size t2->Branch(bname.Data(),&tmpW[j],leafname.Data(),bufsz); } t2->Branch("tmpT",&tmpT,"l/I",bufsz); // tree with 1 branch; one for all struct ts TTree *t3 = new TTree("T3"," Compressed struct ts"); bufsz = 64000; t3->Branch("ts",&ts,"t/I:w[4]/I",bufsz); // create random numb generator object for white noise time series TRandom rndm; //"event" loop for (Int_t i=0; iFill(); t2->Fill(); t3->Fill(); // give some diagnostic info if(!(i%10000)){ printf("i=%d l=%d ;\ntmpTc[0-3]=%d %d %d %d; ch[0-3]=%d %d %d %d\n", i, tmpT.l, tmpT.c[0], tmpT.c[1], tmpT.c[2], tmpT.c[3], ch[0].c, ch[1].c , ch[2].c, ch[3].c); printf("tmpW[0]=%d\n tmpW[0]c[0-3]=%d %d %d %d; ch[4-7]=%d %d %d %d\n", tmpW[0].l, tmpW[0].c[0], tmpW[0].c[1], tmpW[0].c[2], tmpW[0].c[3], ch[4].c, ch[5].c , ch[6].c, ch[7].c); } } // end "event" loop f1.Write(); printf("\n"); t1->Print(); printf("\n"); t2->Print(); printf("\n"); t3->Print(); f1.Close(); }