ROOT:Tips Tricks

From AliceWiki
Jump to: navigation, search


float/double

source


linux, gcc 4.9, glibc 2.20

root [1] float_double()
float  min = 1.17549e-38
float  max = 3.40282e+38
double min = 2.22507e-308
double max = 1.79769e+308
float  epsilon = 0.000000119209289550781250000000000000000000000000000000000000 => 1.19209e-07
double epsilon = 0.000000000000000222044604925031308084726333618164062500000000 => 2.22045e-16


number    1234567890123456789012345.1234567890123456789012345
as float  1234567946798590058299392.000000 => 1.23457e+24
as double 1234567890123456824475648.000000 => 1.23457e+24

number    1234567890123456789012345.0
as float  1234567946798590058299392.000000 => 1.23457e+24
as double 1234567890123456824475648.000000 => 1.23457e+24

number    0.1234567890123456789012345
as float  0.123456791043281555175781250000000000000000000000000000000000 => 0.123457
as double 0.123456789012345677369886232099815970286726951599121093750000 => 0.123457

number    1234567890123456789012345 (no decimal)
as float  1096246353119412224.000000 => 1.09625e+18
as double 1096246371337559936.000000 => 1.09625e+18

number    9.123e+22
as float  91230003119595695636480.000000 => 9.123e+22
as double 91230000000000004718592.000000 => 9.123e+22

number    9.123e+40
as float  inf => inf
as double 91230000000000006312383662990803305758720.000000 => 9.123e+40

number    9.123e-10
as float  0.000000000912300013311551083461381494998931884765625000000000 => 9.123e-10
as double 0.000000000912300000000000044597902336461579114734732343094947 => 9.123e-10

number    9.123e-50
as float  0.000000000000000000000000000000000000000000000000000000000000 => 0
as double 0.000000000000000000000000000000000000000000000000091230000000 => 9.123e-50

other

second bit status word

UShort_t     fBits2;


TClonesArray

loop {
  TClonesArray &hits = *fTDCHits;
  new(hits[fNTDCHits++]) TTDCHit(ch, tld);
}

Uses a TClonesArray which reduces the number of new/delete calls.

V slucke sa stale vola normal constructor (ale bez delete)

loop {
  // TTDCHit *const hit = static_cast<TTDCHit *>(fTDCHits->ConstructedAt(fNTDCHits++));
  TTDCHit *hit = (TTDCHit *)fTDCHits->ConstructedAt(fNTDCHits++);
  hit->Set(ch, tld);
}
hit->SetChannelTime(ch, tld);

To reduce the number of call to the constructor (especially useful if the user class requires memory allocation), the object can be added (and constructed when needed) using ConstructedAt which only calls the constructor once per slot.

Always returns an already constructed object. If the slot is being used for the first time, it calls the default constructor otherwise it returns the object as is (unless a string is passed as the 2nd argument to the function in which case, it also calls Clear(second_argument) on the object). Simpler and more efficient even in case where the TTDCHit/TTrack class allocates memory.

V slucke sa vola sa iba jeden (resp. maximum z fNTDCHits) default constructor. V funkcii Set() preto musim zabezpecit 'resetovanie' premennych (z predchadzajuceho hitu) alebo pouzit/volat extra funkciu hit->Clear() alebo priamo volat ConstructedAt(Int_t idx, Option_t *clear_options). Kedze v TClonesArray mozu byt len objekty odvodene od TObject, moze nastat situacia, ze je potrebne 'resetovat' aj premenne (fUniqueID, fBits) v TObject (TObject::Clear() je na dnesny den prazdna funkcia)

Particle *const p = static_cast<Particle *>(particles_.ConstructedAt(nActive_++));
Event *const newEvent = static_cast<Event *>(events.ConstructedAt(j));

Clone or Copy

What is the actual difference between the results of a TObject->Clone() and TObject->Copy() ?

The difference is the interface (one create a new object, the other update an existing object)

Double_32 dictionary generation

gROOT->ProcessLine("struct D32Holder { Double32_t var; //[0, 4096, 13] };");
myTree->Branch("var", TClass::GetClass("D32Holder"), &var);

myTree->Branch("var", "D32Holder", (void*)&var);

gInterpreter->Declare("struct D32Holder { Double32_t var; //[0, 4096, 13]\n};");
void *p = (void*)&var;
myTree->Branch("var", "D32Holder", (void*)&p);

Tree and SetAutoSave

  • When large Trees are produced, it is safe to activate the AutoSave procedure.
  • Each AutoSave generates a new key on the file. Once the key with the tree header has been written, the previous cycle (if any) is deleted.
  • calling TTree::SetAutoSave with a small value (or calling TTree::AutoSave too frequently) is an expensive operation. You should make tests for your own application to find a compromise between speed and the quantity of information you may loose in case of a job crash.
  • => ak nepotrebujem mat istotu moznosti recovery (napr. straty danych pri necakanom skonceni programu) tak dam velku hodnotu a tree header sa ulozi az uplne na konci, resp. az po velkej hodnote entries/bytes
  • => tree;1 => 1 cycle bude vzdy ak SetAutoSave > entries; inak sa ulozi aj predchadzajuci cycle (for deleting the previous cycle and just stay with the newest one fTree->Write("",kWriteDelete))

test file: tree pp, events = 43714

  • fTree->SetAutoSave(100); // autosave when 100 entries (!!! filling about 10.5 sec. !!!)  !!! expensive operation !!!
pp;438 => 43714 entries
pp;437 => 43700 entries (437*100 = 43700)
  • fTree->SetAutoSave(1000); // autosave when 1000 entries (filling about 2.0 sec.)
pp;44 => 43714 entries
pp;43 => 43000 entries (43*1000 = 43000)
  • fTree->SetAutoSave(50000); // autosave when 50000 entries (filling about 1.5 sec.)
pp;1 => 43714 entries


  • fTree->SetAutoSave(-300000000); // DEFAULT, autosave when 300000000 bytes (unzipped) written (filling about 1.5 sec.)
pp;1 => 43714 entries

misc

rootcint -f TStrawDict.cxx -c TStrawCham.h TStrawTrack.h StrawChamLinkDef.h
g++ -O -fPIC -I$ROOTSYS/include -c TStrawDict.cxx TStrawCham.cxx TStrawTrack.cxx
g++ -g -shared TStrawDict.o TStrawCham.o TStrawTrack.o TStrawDict.o -o libStraw.so


TImage *img = TImage::Create();
img->FromPad(c1, 520, 1100, 630, 600);
img->WriteImage("bla.png");


ProcInfo_t info;
gSystem->GetProcInfo(&info);
Printf("MemResident = %8ld kB, MemVirtual = %8ld kB", info.fMemResident, info.fMemVirtual);


Makefile

ROOT_MAJOR := $(shell $(RC) --version | cut -f1 -d '.')
ROOT_MINOR := $(shell $(RC) --version | cut -f2 -d '.' | cut -f1 -d '/')
ROOT_PATCH := $(shell $(RC) --version | cut -f2 -d '/')
ROOT_VER_INT := $(ROOT_MAJOR)$(ROOT_MINOR)$(ROOT_PATCH)
ROOT_VER_OK  := $(shell [ $(ROOT_VER_INT) -ge 60305 ] && echo ok)

do:
		echo $(ROOT_VER_INT)
		echo $(ROOT_VER_OK)
ifeq ($(ROOT_VER_OK),ok)
		echo "OK version"
else
		echo "BAD version"
endif

Tree compression

data file: /home/musinsky/TQDC_sample/vmeRUN114_2015-02-20_02-24-02.dat
size   = 1672234636 bytes (418058659 words)
spills = 99
events = 2065816

vmeRUN114_2015-02-20_02-24-02.dat => 1595M (SSD disk, PC strela04)
TDC + TQDC
SetCompressionSettings(ROOT::CompressionSettings(ROOT::kUseGlobalSetting, 1)) DEFAULT

root [] .x d.C

settings  1
algorithm 0
level     1
factor    2.79228
Info in <TTDCEvent::~TTDCEvent>: Destructor
Info in <TTQDCEvent::~TTQDCEvent>: Destructor
Real time 0:00:35.814060, CP time 33.160
Real time 0:00:35.260297, CP time 32.980

root [] gStrela->AnalyzeEntries()
Real time 0:00:32.734012, CP time 32.710
Real time 0:00:32.887350, CP time 32.840
TDC + TQDC
SetCompressionSettings(ROOT::CompressionSettings(ROOT::kUseGlobalSetting, 0)) NO COMPRESSION

root [] .x d.C

settings  0
algorithm 0
level     0
factor    1.00001 => vme_data.root => 1187M
Info in <TTDCEvent::~TTDCEvent>: Destructor
Info in <TTQDCEvent::~TTQDCEvent>: Destructor
Real time 0:00:20.595933, CP time 15.830            !!!!!!!!!!!!!!!!!!!!
Real time 0:00:20.444206, CP time 16.220

root [] gStrela->AnalyzeEntries()
Real time 0:00:28.762151, CP time 28.740
Real time 0:00:29.007629, CP time 28.990
TDC + TQDC
SetCompressionSettings(ROOT::CompressionSettings(ROOT::kUseGlobalSetting, 2))

root [] .x d.C

settings  2
algorithm 0
level     2
factor    2.71566
Info in <TTDCEvent::~TTDCEvent>: Destructor
Info in <TTQDCEvent::~TTQDCEvent>: Destructor
Real time 0:00:36.719002, CP time 35.660
Real time 0:00:35.929452, CP time 35.590

root [] gStrela->AnalyzeEntries()
Real time 0:00:32.512738, CP time 32.500
Real time 0:00:32.428839, CP time 32.410
TDC + TQDC
SetCompressionSettings(ROOT::CompressionSettings(ROOT::kUseGlobalSetting, 5))

root [] .x d.C

settings  5
algorithm 0
level     5
factor    2.72555
Info in <TTDCEvent::~TTDCEvent>: Destructor
Info in <TTQDCEvent::~TTQDCEvent>: Destructor
Real time 0:00:56.073635, CP time 54.390
Real time 0:00:56.018901, CP time 54.940

root [] gStrela->AnalyzeEntries()
Real time 0:00:32.388135, CP time 32.360
Real time 0:00:32.398775, CP time 32.380
TDC + TQDC
SetCompressionSettings(ROOT::CompressionSettings(ROOT::kUseGlobalSetting, 9))

root [] .x d.C

settings  9
algorithm 0
level     9
factor    2.75533
Info in <TTDCEvent::~TTDCEvent>: Destructor
Info in <TTQDCEvent::~TTQDCEvent>: Destructor
Real time 0:03:01.095543, CP time 180.740
Real time 0:02:59.151411, CP time 178.600

root [] gStrela->AnalyzeEntries()
Real time 0:00:32.280681, CP time 32.270
Real time 0:00:32.255684, CP time 32.230


C/C++ stack/heap

// funkcia
int getaddrinfo(p1, p2, p3, struct addrinfo **res);

// priame volanie
struct addrinfo *result;
getaddrinfo(p1, p2, p3, &result);
// retrieving a pointer to pointer (the addrinfo list head)
void GetAddrInfo(struct addrinfo **update)
{
   getaddrinfo(p1, p2, p3, update);
}

struct addrinfo *myresult;
GetAddrInfo(&myresult);

// or
void GetAddrInfo(struct addrinfo **update)
{
   struct addrinfo *res;
   getaddrinfo(p1, p2, p3, &res);
   *update = res;   // save the pointer to the struct
}

struct addrinfo *myresult;
GetAddrInfo(&myresult);

C/C++ difference

C style pass-by-reference (C or C++)

int x = 0;
fun(&x);
// now x = 1

fun(int *xx)
   *xx = 1;

C++ style pass-by-reference (only C++)

int x = 0;
fun(x);
// now x = 1

fun(int &xx)
   xx = 1;
  • exit vs. return: exit = All open stdio(3) streams are flushed and closed. Files created by tmpfile(3) are removed ...

sizeof

  • sizeof is a compile time operator
  • sizeof is evaluated at compile time
  • sizeof is always computed at compile time in C89. Since C99 and variable length arrays, it is computed at run time when a variable length array is part of the expression in the sizeof operand.

mc

# ROOT
shell/i/.root
        View=%view{ascii} rootls -1lt %f 2>/dev/null