double32.C

Go to the documentation of this file.
00001 //////////////////////////////////////////////////////////////////////////////
00002 //
00003 //+  Tutorial illustrating use and precision of the Double32_t data type
00004 //
00005 // You must run this tutorial with ACLIC
00006 //    root > .x double32.C+
00007 //
00008 // The following cases are supported for streaming a Double32_t type
00009 // depending on the range declaration in the comment field of the data member:
00010 //  A-    Double32_t     fNormal;
00011 //  B-    Double32_t     fTemperature; //[0,100]
00012 //  C-    Double32_t     fCharge;      //[-1,1,2]
00013 //  D-    Double32_t     fVertex[3];   //[-30,30,10]
00014 //  E-    Double32_t     fChi2;        //[0,0,6]
00015 //  F-    Int_t          fNsp;
00016 //        Double32_t*    fPointValue;   //[fNsp][0,3]
00017 //
00018 // In case A fNormal is converted from a Double_t to a Float_t
00019 // In case B fTemperature is converted to a 32 bit unsigned integer
00020 // In case C fCharge is converted to a 2 bits unsigned integer
00021 // In case D the array elements of fVertex are converted to an unsigned 10 bits integer
00022 // In case E fChi2 is converted to a Float_t with truncated precision at 6 bits
00023 // In case F the fNsp elements of array fPointvalue are converted to an unsigned 32 bit integer
00024 //           Note that the range specifier must follow the dimension specifier.
00025 // the case B has more precision (9 to 10 significative digits than case A (6 to 7 digits).
00026 //
00027 // The range specifier has the general format: [xmin,xmax] or [xmin,xmax,nbits]
00028 //  [0,1]
00029 //  [-10,100];
00030 //  [-pi,pi], [-pi/2,pi/4],[-2pi,2*pi]
00031 //  [-10,100,16]
00032 //  [0,0,8]
00033 // if nbits is not specified, or nbits <2 or nbits>32 it is set to 32
00034 // if (xmin==0 and xmax==0 and nbits <=14) the double word will be converted
00035 // to a float and its mantissa truncated to nbits significative bits.
00036 //
00037 // IMPORTANT NOTE
00038 // --------------
00039 // Lets assume an original variable double x:
00040 // When using the format [0,0,8] (ie range not specified) you get the best
00041 // relative precision when storing and reading back the truncated x, say xt.
00042 // The variance of (x-xt)/x will be better than when specifying a range
00043 // for the same number of bits. However the precision relative to the 
00044 // range (x-xt)/(xmax-xmin) will be worst, and vice-versa.
00045 // The format [0,0,8] is also interesting when the range of x is infinite
00046 // or unknown.
00047 //
00048 //Author: Rene Brun
00049 //
00050 ///////////////////////////////////////////////////////////////////////////
00051 
00052 #include "TFile.h"
00053 #include "TCanvas.h"
00054 #include "TTree.h"
00055 #include "TH1.h"
00056 #include "TMath.h"
00057 #include "TRandom3.h"
00058 #include "TGraph.h"
00059 #include "TLegend.h"
00060 #include "TFrame.h"
00061 #include "TPaveLabel.h"
00062    
00063 class DemoDouble32  {
00064 private:
00065    Double_t    fD64;     //reference member with full double precision
00066    Double32_t  fF32;     //saved as a 32 bit Float_t
00067    Double32_t  fI32;     //[-pi,pi]    saved as a 32 bit unsigned int
00068    Double32_t  fI30;     //[-pi,pi,30] saved as a 30 bit unsigned int
00069    Double32_t  fI28;     //[-pi,pi,28] saved as a 28 bit unsigned int
00070    Double32_t  fI26;     //[-pi,pi,26] saved as a 26 bit unsigned int
00071    Double32_t  fI24;     //[-pi,pi,24] saved as a 24 bit unsigned int
00072    Double32_t  fI22;     //[-pi,pi,22] saved as a 22 bit unsigned int
00073    Double32_t  fI20;     //[-pi,pi,20] saved as a 20 bit unsigned int
00074    Double32_t  fI18;     //[-pi,pi,18] saved as a 18 bit unsigned int
00075    Double32_t  fI16;     //[-pi,pi,16] saved as a 16 bit unsigned int
00076    Double32_t  fI14;     //[-pi,pi,14] saved as a 14 bit unsigned int
00077    Double32_t  fI12;     //[-pi,pi,12] saved as a 12 bit unsigned int
00078    Double32_t  fI10;     //[-pi,pi,10] saved as a 10 bit unsigned int
00079    Double32_t  fI8;      //[-pi,pi, 8] saved as a  8 bit unsigned int
00080    Double32_t  fI6;      //[-pi,pi, 6] saved as a  6 bit unsigned int
00081    Double32_t  fI4;      //[-pi,pi, 4] saved as a  4 bit unsigned int
00082    Double32_t  fI2;      //[-pi,pi, 2] saved as a  2 bit unsigned int
00083    Double32_t  fR14;     //[0,  0, 14] saved as a 32 bit float with a 14 bits mantissa
00084    Double32_t  fR12;     //[0,  0, 12] saved as a 32 bit float with a 12 bits mantissa
00085    Double32_t  fR10;     //[0,  0, 10] saved as a 32 bit float with a 10 bits mantissa
00086    Double32_t  fR8;      //[0,  0,  8] saved as a 32 bit float with a  8 bits mantissa
00087    Double32_t  fR6;      //[0,  0,  6] saved as a 32 bit float with a  6 bits mantissa
00088    Double32_t  fR4;      //[0,  0,  4] saved as a 32 bit float with a  4 bits mantissa
00089    Double32_t  fR2;      //[0,  0,  2] saved as a 32 bit float with a  2 bits mantissa
00090        
00091 public:
00092    DemoDouble32() {;}
00093    void Set(Double_t ref);
00094 };
00095 
00096 void DemoDouble32::Set(Double_t ref) {
00097    fD64 = fF32 = fI32 = fI30 = fI28 = fI26 = fI24 = fI22 = fI20 = ref;
00098    fI18 = fI16 = fI14 = fI12 = fI10 = fI8  = fI6  = fI4  = fI2  = ref;
00099    fR14 = fR12 = fR10 = fR8  = fR6  = fR4  = fR2  = ref;
00100 }
00101       
00102 void double32() {
00103    // show the use and precision of the Double32_t data type
00104    
00105    DemoDouble32 *d = new DemoDouble32();
00106    
00107    //create a Tree with 40000 objects DemoDouble32
00108    TFile::Open("DemoDouble32.root","recreate");
00109    TTree *T = new TTree("T","DemoDouble32");
00110    TBranch *bd = T->Branch("d","DemoDouble32",&d,4000);
00111    TRandom3 r;
00112    Double_t xmax = TMath::Pi();
00113    Double_t xmin = -xmax;
00114    Int_t i, n = 40000;
00115    for (i=0;i<n;i++) {
00116       d->Set(r.Uniform(xmin,xmax));
00117       T->Fill();
00118    }
00119    T->Write();
00120    
00121    //Create the frame histogram and the graphs
00122    TObjArray *branches = bd->GetListOfBranches();
00123    Int_t nb = branches->GetEntries();
00124    TBranch *br = (TBranch*)branches->At(0);
00125    Long64_t zip64 = br->GetZipBytes();
00126    Double_t cx = 1;
00127    Double_t drange = 15;
00128    Double_t dval = 15;
00129    TCanvas *c1 = new TCanvas("c1","c1",800,600);
00130    c1->SetGrid();
00131    c1->SetHighLightColor(0);
00132    c1->SetFillColor(17);
00133    c1->SetFrameFillColor(20);
00134    c1->SetFrameBorderSize(10);
00135    TH1F *h = new TH1F("h","",nb,0,nb);
00136    h->SetMaximum(16);
00137    h->SetStats(0);
00138    h->Draw();
00139    c1->GetFrame()->SetFillColor(21);
00140    c1->GetFrame()->SetBorderSize(12);
00141    TGraph *gcx = new TGraph(nb); gcx->SetName("gcx");
00142    gcx->SetMarkerStyle(21);
00143    gcx->SetMarkerColor(kBlue);
00144    TGraph *gdrange = new TGraph(nb); gdrange->SetName("gdrange");
00145    gdrange->SetMarkerStyle(20);
00146    gdrange->SetMarkerColor(kRed);
00147    TGraph *gdval = new TGraph(nb); gdval->SetName("gdval");
00148    gdval->SetMarkerStyle(20);
00149    gdval->SetMarkerColor(kBlack);
00150    TPaveLabel *title = new TPaveLabel(.15,.92,.85,.97,"Double32_t compression and precision","brNDC");   
00151    title->Draw();
00152    
00153    //loop on branches to get the precision and compression factors
00154    for (i=0;i<nb;i++) {
00155       br = (TBranch*)branches->At(i);
00156       h->GetXaxis()->SetBinLabel(i+1,br->GetName());
00157       cx = Double_t(zip64)/Double_t(br->GetZipBytes());
00158       gcx->SetPoint(i,i+0.5,cx);
00159       if (i > 0) {
00160          T->Draw(Form("(fD64-%s)/(%g)",br->GetName(),xmax-xmin),"","goff");
00161          Double_t rms = TMath::RMS(n,T->GetV1());
00162          drange = TMath::Max(0.,-TMath::Log10(rms));
00163       }
00164       gdrange->SetPoint(i,i+0.5,drange);
00165       if (i > 0) {
00166          T->Draw(Form("(fD64-%s)/(fD64+0.01)",br->GetName()),"","goff");
00167          Double_t rms = TMath::RMS(n,T->GetV1());
00168          dval = TMath::Max(0.,-TMath::Log10(rms));
00169       }
00170       gdval->SetPoint(i,i+0.5,dval);
00171    }
00172    gcx->Draw("lp");
00173    gdrange->Draw("lp");
00174    gdval->Draw("lp");
00175    TLegend *legend = new TLegend(0.2,0.7,0.7,0.85);
00176    legend->SetTextFont(72);
00177    legend->SetTextSize(0.04);
00178    legend->AddEntry(gcx,"Compression factor","lp");
00179    legend->AddEntry(gdrange,"Log of precision wrt range","lp");
00180    legend->AddEntry(gdval,"Log of precision wrt value","lp");
00181    legend->Draw();
00182    TPaveLabel *rang = new TPaveLabel(.75,.75,.88,.80,"[-pi,pi]","brNDC");   
00183    rang->Draw();
00184 }
00185    
00186    
00187    
00188        

Generated on Tue Jul 5 15:44:49 2011 for ROOT_528-00b_version by  doxygen 1.5.1