]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/CDB/AliOCDBtoolkit.cxx
Merge branch 'master' of https://git.cern.ch/reps/AliRoot
[u/mrichter/AliRoot.git] / STEER / CDB / AliOCDBtoolkit.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /*
17
18   Primary goal of the proposal was to provide functionality to browse and compare the content of the OCDB
19   specified by different means.
20
21   a.) galice.root               - as currently implemented by Ruben in MC (or any file with cdbMap, and cdbList)
22   b.) AliESDs.root              - for the reconstructed data
23   c.) ocdb snapshot             - as used for grid productions
24   d.) TMap(s)                   - as used internally in galice.root and AliESDs,root  
25   e.) log file (if possible)    - looks logs aways used similar syntax, tested and working
26   f.) C macro                   - custom macro
27
28   Content comparison should be done:
29   a.) on the level of symbolic links 
30   b.) on the level of content itself 
31   - by by byte comparison dif
32   - data member by data member comparison
33
34   Implementation assumption:
35   All input formats (a .. f) will  be converted to the TMap storages and TList if AliCDBIds 
36
37   Example usage:
38   AliOCDBtoolkit::MakeDiffExampleUseCase();
39
40
41
42   //=============================================================================
43   // Functionality to dump content of  objects in human readable format
44   //=============================================================================
45   Use case examples 
46   1.) compare oontent of alignent OCDB files for differnt yers
47   2.) compare ClusterParam for different periods
48   
49   
50    
51   =================================================================================================================
52   // 1.)
53   // Compare alignment example:
54   // Compare TPC alignemnt 2013 and 2010
55   //
56   AliOCDBtoolkit::DumpOCDBFile("/cvmfs/alice.gsi.de/alice/data/2013/OCDB/TPC/Align/Data/Run0_999999999_v1_s0.root","TPCalign2013.dump",1,1);
57   AliOCDBtoolkit::DumpOCDBFile("/cvmfs/alice.gsi.de/alice/data/2010/OCDB/TPC/Align/Data/Run0_999999999_v1_s0.root","TPCalign2010.dump",1,1);
58   diff  TPCalign2013.dump TPCalign2010.dump > TPCalign2013_TPCalign2010.diff
59   //
60   //    
61   =================================================================================================================
62   //  2.) 
63   // Compare CluterParam OCDB etry
64   //
65   AliOCDBtoolkit::DumpOCDBFile("/cvmfs/alice.gsi.de/alice/data/2010/OCDB/TPC/Calib/ClusterParam/Run131541_999999999_v2_s0.root","2010_TPC_Calib_ClusterParam_Run131541_999999999_v2_s0.dump",1);
66   AliOCDBtoolkit:: AliOCDBtoolkit::DumpOCDBFile("/cvmfs/alice.gsi.de/alice/data/2010/OCDB/TPC/Calib/ClusterParam/Run0_999999999_v1_s0.root","2010_TPC_Calib_ClusterParam_Run0_999999999_v1_s0.dump",1);
67   AliOCDBtoolkit::DumpOCDBFile("/cvmfs/alice.gsi.de/alice/data/2013/OCDB/TPC/Calib/ClusterParam/Run0_999999999_v1_s0.root","2013_TPC_Calib_ClusterParam_Run0_999999999_v1_s0.dump",1);
68   diff 2010_TPC_Calib_ClusterParam_Run131541_999999999_v2_s0.dump 2010_TPC_Calib_ClusterParam_Run0_999999999_v1_s0.dump
69  
70
71 */
72
73
74 using namespace std;
75
76 // STD
77 #include <iostream>
78 #include <algorithm>
79 #include <sstream>
80 #include <stdexcept>
81 #include <functional>
82 #include "TRealData.h"
83 #include "TDataMember.h"
84 #include "TClass.h"
85 #include "TROOT.h"
86 #include <TVectorD.h>
87 //
88 #include "TSystem.h"
89 #include "TObjArray.h"
90 #include "TString.h"
91 #include "TTree.h"
92 #include "TMessage.h"
93 //
94 #include "AliCDBManager.h"
95 #include "AliCDBEntry.h"
96 #include "AliOCDBtoolkit.h"
97 #include "AliCDBStorage.h"
98
99
100 void AliOCDBtoolkit::MakeDiffExampleUseCase(){
101   //
102   // Example usage for the MC 
103   // To run example case, assuming presence of following files in working directory: 
104   //    - rec.log        
105   //    - galice.root   
106   //    - AliESDs.root
107   //
108   AliCDBManager * man = AliCDBManager::Instance();
109   LoadOCDBFromLog("rec.log",0);
110   const TMap *cdbMapLog= man->GetStorageMap();        // this is map of 
111   const TList *cdbListLog=man->GetRetrievedIds();     // this is list of AliCDBId
112   //  TList *cdbListLog0=man->GetRetrievedIds();     // this is list of AliCDBId
113   //
114   TFile *fmc = TFile::Open("galice.root");
115   TMap *cdbMapMC= (TMap*)fmc->Get("cdbMap");          // 
116   TList *cdbListMC0= (TList*)fmc->Get("cdbList");     // this is list of TObjStrings
117   TList *cdbListMC = ConvertListStringToCDBId(cdbListMC0);        // convert to the TObjArray of AliCDBids
118   //
119   TFile *fesd = TFile::Open("AliESDs.root");
120   TList *listESD = ((TTree*)fesd->Get("esdTree"))->GetUserInfo();
121   TMap *cdbMapESD= (TMap*)listESD->FindObject("cdbMap");  
122   TList *cdbListESD0= (TList*)listESD->FindObject("cdbList"); // this is list of TObjStrings
123   TList *cdbListESD = ConvertListStringToCDBId(cdbListESD0);              // convert to the TObjArray  of AliCDBids
124   //
125   //
126   //
127   printf("\n\n");
128   printf("Diff log>>>ESD\n\n:");
129   MakeDiff(cdbMapLog, cdbListLog, cdbMapESD, cdbListESD,0);
130   printf("\n\n");
131   printf("Diff ESD>>>log\n\n:");
132   MakeDiff(cdbMapESD, cdbListESD,cdbMapLog, cdbListLog,0);
133   // 
134   printf("\n\n");
135   printf("Diff ESD>>>MC\n\n:");
136   MakeDiff(cdbMapMC, cdbListMC, cdbMapESD, cdbListESD,0);
137 }
138
139
140 void AliOCDBtoolkit::DumpOCDBAsTxt(const TString fInput, const TString fType, const TString outfile){
141   //
142   //
143   //
144   TFile *file;
145   const TMap *cdbMap;
146   const TList *cdbList;
147   //
148   //
149   
150   if(fType.EqualTo("MC",TString::kIgnoreCase)){
151         file = TFile::Open(fInput.Data());
152         cdbMap = (TMap*)file->Get("cdbMap");          // 
153         TList *cdbListMC0 = (TList*)file->Get("cdbList");     // this is list of TObjStrings
154         cdbList = ConvertListStringToCDBId(cdbListMC0);        // convert to the TObjArray of AliCDBids
155   } 
156     else if(fType.EqualTo("ESD",TString::kIgnoreCase)){
157       file = TFile::Open(fInput.Data());
158       TList *listESD = ((TTree*)file->Get("esdTree"))->GetUserInfo();
159       cdbMap = (TMap*)listESD->FindObject("cdbMap");  
160       TList *cdbListESD0= (TList*)listESD->FindObject("cdbList"); // this is list of TObjStrings
161       cdbList = ConvertListStringToCDBId(cdbListESD0);              // convert to the TObjArray  of AliCDBids
162     }
163     else if(fType.EqualTo("log",TString::kIgnoreCase)){
164         AliCDBManager * man = AliCDBManager::Instance();
165         LoadOCDBFromLog(fInput.Data(),0);
166         cdbMap = man->GetStorageMap();        // this is map of 
167         cdbList =man->GetRetrievedIds();     // this is list of AliCDBId
168     }
169     else{
170         printf("unsupported option: %s",fType.Data());
171         return;
172     }
173   cout <<"BEGINDUMP:" << endl;
174   DumpOCDB(cdbMap,cdbList,outfile);
175 }
176
177
178 Bool_t AliOCDBtoolkit::ParseInfoFromOcdbString(TString ocdbString, TString &ocdbPath, Int_t &run0, Int_t &run1, Int_t &version, Int_t &subVersion){
179   //
180   // Parse OCDB id string and provide basic ocdb information
181   //
182   //  a.) parse ocdbPath
183   Int_t indexBeginPath= ocdbString.Index("path: ")+7;
184   if (indexBeginPath<0) return kFALSE;
185   Int_t indexEndPath=ocdbString.Index(";",indexBeginPath);
186   if (indexEndPath<0) return kFALSE;
187   ocdbPath=TString(&(ocdbString.Data()[indexBeginPath]), indexEndPath-indexBeginPath-1);
188   // b.) parse runRange
189   Int_t indexRun0= ocdbString.Index(": [",indexEndPath)+3;
190   if (indexRun0<0) return kFALSE;
191   Int_t indexRun1= ocdbString.Index(",",indexRun0)+1;
192   if (indexRun1<0) return kFALSE;
193   run0=atoi(&(ocdbString.Data()[indexRun0]));
194   run1=atoi(&(ocdbString.Data()[indexRun1]));
195   AliCDBRunRange runRange(run0,run1);
196   //c.) parse version, subversion
197   Int_t indexVersion= ocdbString.Index("version: v",indexRun1)+10;
198   if (indexVersion<0) return kFALSE;
199   Int_t indexSubVersion= ocdbString.Index("_s",indexVersion)+2;
200   if (indexSubVersion<0) return kFALSE;
201   version=atoi(&(ocdbString.Data()[indexVersion]));
202   subVersion=atoi(&(ocdbString.Data()[indexSubVersion]));
203   return kTRUE;
204 }
205
206 Bool_t AliOCDBtoolkit::ParseInfoFromOcdbString(TString ocdbString, AliCDBId &cdbId){
207   //
208   // Parse OCDB id string and provide basic ocdb information and fillcdbID object
209   //
210   TString ocdbPath;
211   Int_t run0=0, run1=0;
212   Int_t version=0, subVersion=0;
213   Bool_t parseStatus = ParseInfoFromOcdbString(ocdbString, ocdbPath, run0,run1,version,subVersion); 
214   if (parseStatus) {
215     AliCDBRunRange runRange(run0,run1);
216     cdbId=AliCDBId(ocdbPath.Data(),runRange,version,subVersion);
217     AliCDBId* id = AliCDBId::MakeFromString(ocdbString);
218     cdbId=*id;
219     delete id;
220   }
221   //
222   return parseStatus;
223 }
224
225 TList  * AliOCDBtoolkit::ConvertListStringToCDBId(const TList *cdbList0){
226   //
227   // Convert input  list of the TObjString to list to AliCDBid 
228   //
229   Int_t entriesList0=cdbList0->GetEntries();
230   TList * array0 = new TList();
231   AliCDBId tmp0;
232   for (Int_t ientry0=0; ientry0<entriesList0; ientry0++){
233     if (cdbList0->At(ientry0)==0) continue;
234     Bool_t isId =  cdbList0->At(ientry0)->IsA()->InheritsFrom("AliCDBId");
235     if (isId){
236       array0->AddLast(cdbList0->At(ientry0));
237     }else{
238       Bool_t isString =  cdbList0->At(ientry0)->IsA()->InheritsFrom("TObjString");
239       if (isString){
240         TObjString* sid0 = dynamic_cast<TObjString*> (cdbList0->At(ientry0));
241         Bool_t status =  ParseInfoFromOcdbString(sid0->String(), tmp0);
242         if (!status) continue;
243         array0->AddLast(new AliCDBId(tmp0));
244       }
245     }
246   }
247   return array0;  
248 }
249
250
251
252 void AliOCDBtoolkit::LoadOCDBFromLog(const char *logName, Int_t verbose){
253   //
254   // Initilaize OCDB
255   // Load OCDB setting as specified in log
256   // Assuming fixed version of the log 
257   // AliCDBManager is initilaized - ocdbMap and ID list can be exported
258   //
259
260   // Parsing/loading sequence:
261   //    0.) SetDefault storage  *** Default Storage URI:
262   //    1.) SetSpecific storage  *** Specific storage
263   //    2.) SetRunNumber  Run number:
264   //    3.) Set used IDs
265   //
266   AliCDBManager * man = AliCDBManager::Instance();
267   //
268   // 0.) SetDefault storage  *** Default Storage URI:
269   // 
270   TString  defaultOCDB = gSystem->GetFromPipe(TString::Format("cat %s| grep \"Storage URI:\"",logName).Data());
271   TObjArray *array = defaultOCDB.Tokenize("\"");
272   man->SetDefaultStorage(array->Last()->GetName());
273   delete array;
274   //
275   // 1.) SetSpecific storage  *** Specific storage
276   //
277   TString  specificStorage  = gSystem->GetFromPipe(TString::Format("cat %s| grep \"Specific storage\"",logName).Data());
278   array = specificStorage.Tokenize("\"");
279   Int_t entries = array->GetEntries();
280   for (Int_t i=1; i<entries-2; i+=4){    
281     // add protection here line shuld be in expected format
282     if ((verbose&2)>0) printf("%s\t%s\n",array->At(i)->GetName(),array->At(i+2)->GetName());    
283     man->SetSpecificStorage(array->At(i)->GetName(),array->At(i+2)->GetName());
284   }
285   delete array;
286   //
287   // 2.) SetRunNumber  Run number:
288   //
289   TString  runLine  = gSystem->GetFromPipe(TString::Format("cat %s| grep \"I-AliCDBManager::Print: Run number =\"",logName).Data());
290   array = runLine.Tokenize("=");
291   Int_t run = 0;
292   if (array->GetEntries()>1) run=atoi(array->At(1)->GetName()); 
293   delete array;
294   man->SetRun(run);  
295   //
296   // 3.) Set used IDs
297   //   
298   TString  ids =   gSystem->GetFromPipe(TString::Format("cat %s| grep I-AliCDB | grep path| grep range | grep version", logName).Data());
299   array= ids.Tokenize("\n");
300   entries = array->GetEntries();
301   //
302   for (Int_t i=0; i<entries; i++){
303     //
304     TString ocdbString = array->At(i)->GetName();
305     TString ocdbEntry;
306     TString ocdbPath;
307     Int_t run0=0, run1=0;
308     Int_t version=0, subVersion=0;
309     Bool_t parseStatus = ParseInfoFromOcdbString(ocdbString, ocdbPath, run0,run1,version,subVersion); 
310     if (!parseStatus) continue;
311     AliCDBRunRange runRange(run0,run1);
312     //
313     if ((verbose&2)!=0) {
314       printf("%s/Run%d_%d_v%d_s%d.root\n",ocdbPath.Data(),run0,run1,version,subVersion); 
315     }
316     try {
317       man->Get(ocdbPath.Data(),runRange,version,subVersion);      
318     } catch(const exception &e){
319       cerr << "OCDB retrieval failed!" << endl;
320       cerr << "Detailes: " << e.what() << endl;
321     }    
322   }  
323   if ((verbose&1)!=0){
324     man->Print();
325     man->GetStorageMap()->Print();
326     man->GetRetrievedIds()->Print(); 
327   }
328 }
329
330
331 void AliOCDBtoolkit::LoadOCDBFromMap(const TMap */*cdbMap*/, const TList */*cdbList*/){
332   //
333   // Initilaize OCDB
334   // Load OCDB setting as specified in maps
335   // Or Do we have already implementation in AliCDBanager?
336 }
337
338
339
340 void AliOCDBtoolkit::MakeDiff(const TMap */*cdbMap0*/, const TList *cdbList0, const TMap */*cdbMap1*/, const TList *cdbList1, Int_t /*verbose*/){
341   //
342   //
343   // Print difference between the 2 ocdb maps
344   // Input:
345   //   maps and list charactireizing OCDB setup  
346   // Output:
347   //   To be decided, currently it is the teinal output
348   //
349   Int_t entriesList0=cdbList0->GetEntries();
350   Int_t entriesList1=cdbList1->GetEntries();
351   //
352   for (Int_t ientry0=0; ientry0<entriesList0; ientry0++){
353     AliCDBId *id0    = dynamic_cast<AliCDBId*> (cdbList0->At(ientry0));
354     AliCDBId *id1=0;
355     for (Int_t ientry1=0; ientry1<entriesList1; ientry1++){
356       AliCDBId *cid1    = dynamic_cast<AliCDBId*> (cdbList1->At(ientry1));
357       //id0.Print();
358       //cid1.Print();
359       if (cid1->GetPath().Contains(id0->GetPath().Data())==0) continue;
360       id1=cid1;
361     }
362     if (!id1) {
363       printf("Missing entry\t");
364       id0->Print();
365       continue;
366     }
367     //   Bool_t isOK=kTRUE;
368     if (id0->GetFirstRun()!= id1->GetFirstRun() ||id0->GetLastRun()!= id1->GetLastRun()){
369       printf("Differrent run range\n");
370       id0->Print();
371       id1->Print();
372     }    
373     if (id0->GetVersion()!= id1->GetVersion() ||id0->GetSubVersion()!= id1->GetSubVersion()){
374       printf("Differrent version\n");
375       id0->Print();
376       id1->Print();
377     }    
378   }
379 }
380
381 void AliOCDBtoolkit::DumpOCDB(const TMap *cdbMap0, const TList *cdbList0, const TString outfile){
382   //
383   // Dump the OCDB configuatation as formated text file 
384   // with following collumns
385   // cdb name  prefix cdb path
386   // OCDB entries are sorted alphabetically
387   // e.g:
388   // TPC/Calib/RecoParam /hera/alice/jwagner/software/aliroot/AliRoot_TPCdev/OCDB/ TPC/Calib/RecoParam/Run0_999999999_v0_s0.root $SIZE_AliCDBEntry_Object $HASH_AliCDBEntry_Object
389   
390   AliCDBManager * man = AliCDBManager::Instance();
391   
392   TList * cdbList = (TList*) cdbList0;   // sorted array
393   cdbList->Sort();
394
395   TIter next(cdbList);
396   AliCDBId *CDBId;
397   TString cdbName;
398   TString cdbPath;
399   TObjString *ostr;
400   AliCDBEntry *cdbEntry;
401   UInt_t hash;
402   TMessage * file;
403   Int_t size; 
404   FILE *ofs = fopen(outfile.Data(),"w");
405   
406   while ((CDBId  =(AliCDBId*) next())){
407     cdbName = CDBId->GetPath();
408     ostr = (TObjString*)cdbMap0->GetValue(cdbName.Data());
409     if(!ostr) ostr = (TObjString*)cdbMap0->GetValue("default");
410     cdbPath = ostr->GetString();
411     if(cdbPath.Contains("local://"))cdbPath=cdbPath(8,cdbPath.Length()).Data();
412     
413     cdbEntry = (AliCDBEntry*) man->Get(*CDBId);
414     TObject *obj = cdbEntry->GetObject();
415     file = new TMessage(TBuffer::kWrite);
416     file->WriteObject(obj);
417     size = file->Length();
418     if(!obj){
419       fprintf(ofs,"object %s empty!\n",cdbName.Data());
420       continue;
421     }
422     hash = TString::Hash(file->Buffer(),size);
423     fprintf(ofs,"%s\t%s\t%s/Run%d_%d_v%d_s%d.root\t%d\t%u\n",
424            cdbName.Data(),
425            cdbPath.Data(),
426            cdbName.Data(),
427            CDBId->GetFirstRun(),
428            CDBId->GetLastRun(),
429            CDBId->GetVersion(),
430            CDBId->GetSubVersion(),
431            size,
432            hash
433            );
434     //if(!(CDBId->GetPathLevel(0)).Contains("TPC")) continue;
435     //cout << CDBId.ToString() << endl;
436     delete file;
437   }
438   fclose(ofs);
439 }
440
441
442 //====================================================================================================
443 //  Dump object part
444 //==================================================================================================== 
445
446
447
448
449
450 void AliOCDBtoolkit::DumpOCDBFile(const char *finput , const char *foutput, Bool_t dumpMetaData, Bool_t xml){
451   //
452   //  
453   //  DumpOCDBFile("$ALICE_ROOT/OCDB/ITS/Align/Data/Run0_999999999_v0_s0.root", "ITS_Align_Data_Run0_999999999_v0_s0.dump")
454   //
455   if (finput==0) return ;
456   TFile *falignITS  = TFile::Open(finput);
457   AliCDBEntry *entry  = (AliCDBEntry*)falignITS->Get("AliCDBEntry");
458   if (!entry) return; 
459   TObject *obj = ((AliCDBEntry*)falignITS->Get("AliCDBEntry"))->GetObject();  
460
461   //
462   if (!xml){
463     if (dumpMetaData) gROOT->ProcessLine(TString::Format("((TObject*)%p)->Dump(); >%s",entry, foutput).Data());
464     if (!obj) return;
465     gROOT->ProcessLine(TString::Format("AliOCDBtoolkit::DumpObjectRecursive((TObject*)%p); >>%s",obj, foutput).Data());
466   }
467   if (xml){
468     TFile * f = TFile::Open(TString::Format("%s.xml",foutput).Data(),"recreate");
469     if (dumpMetaData) entry->Write("AliCDBEntry");
470     else obj->Write("AliCDBEntry");
471     f->Close();
472   }
473 }
474
475
476
477 void AliOCDBtoolkit::DumpObjectRecursive(TObject *obj){
478   //
479   //
480   //
481   Int_t counterRec=0;
482   printf("==> Dumping object at: %p, name=%s, class=%s)\n", obj, obj->GetName(), (obj->IsA()->GetName()));
483   DumpObjectRecursive(obj, TString(obj->IsA()->GetName())+".",counterRec);
484 }
485  
486 //
487 //
488 //
489 void AliOCDBtoolkit::DumpObjectRecursive(TObject *obj, TString prefix, Int_t &counterRec){
490   //
491   // Recursive dump of the TObject
492   // Dump all basic types and follow pointers to the objects
493   // current limitation:
494   //    a.) clases and structures not derived from TObject not followed (to fix)
495   //    b.) dynamic arrays not followed
496   //    c.) std maps,array ....  not followed
497   //    
498   //
499   if (!obj) return;
500   //
501   // Special case of Collection classes
502   //
503   if (obj->IsA()->InheritsFrom(TCollection::Class())) {
504     TIter myiter((TCollection*)obj);
505     TObject  *arObject=0;
506     Int_t counter=0;
507     while ((arObject = (TObject*)myiter.Next())) {
508       TString prefixArr = TString::Format("%s[%d]",prefix.Data(),counter);
509       DumpObjectRecursive(arObject,prefixArr,counterRec);
510       counter++;
511     } 
512     counterRec++;
513     return;
514   }
515
516   TClass * cl = obj->IsA();
517   if (!(cl->GetListOfRealData())) cl->BuildRealData();
518   TRealData* rd = 0;
519   TIter next(cl->GetListOfRealData());  
520   while ((rd = (TRealData*) next())) {
521     counterRec++;
522     TDataMember* dm = rd->GetDataMember();
523     TDataType* dtype = dm->GetDataType();
524     Int_t offset = rd->GetThisOffset();
525     char* pointer = ((char*) obj) + offset;
526     
527     if (dm->IsaPointer()) {
528       // We have a pointer to an object or a pointer to an array of basic types.
529       TClass* clobj = 0;
530       if (!dm->IsBasic()) {
531         clobj = TClass::GetClass(dm->GetTypeName());
532       }
533       if (clobj) {
534         // We have a pointer to an object.
535         //
536         if (!clobj->InheritsFrom(TObject::Class())) {
537           // It must be a TObject object.
538           continue; 
539         }
540         char** apointer = (char**) pointer;
541         TObject* robj = (TObject*) *apointer;
542         //      
543         if(!robj)
544           printf("M:%s%s\n",prefix.Data(),dm->GetName()); // Missing - 0 pointer
545         else{
546           printf("T:%s\t%s%s\n", clobj->GetName(),prefix.Data(), dm->GetName());
547           TString prefixNew=prefix;
548           prefixNew+=dm->GetName();
549           prefixNew+=".";
550           if (robj!=obj) DumpObjectRecursive(robj,prefixNew,counterRec);  // trivial check 
551           if (robj==obj){
552             printf("R:%s\t%s%s\n",clobj->GetName(),prefix.Data(), dm->GetName());
553           }
554         }
555       }
556     } else if (dm->IsBasic()) {
557       //
558       // Basic data type
559       //
560       const char* index = dm->GetArrayIndex();
561       if (dm->GetArrayDim()==0){
562         printf("B:\t%s%s\t%s\n", prefix.Data(),rd->GetName(), dtype->AsString(pointer));
563       }
564       //
565       // Basic array - fixed length
566       //
567       //      if (dm->GetArrayDim()>0 && strlen(index) != 0){
568       if (dm->GetArrayDim()>0 ){
569         printf("A:\t%s%s\t",prefix.Data(),rd->GetName());
570         Int_t counter=0;
571         for  (Int_t idim=0; idim<dm->GetArrayDim(); idim++){
572           //printf("A:%d\t%d\n", dm->GetArrayDim(),dm->GetMaxIndex(idim));
573           for (Int_t j=0; j<dm->GetMaxIndex(idim); j++){
574             printf("%s\t",dtype->AsString(pointer+dm->GetUnitSize()*counter));
575             counter++;
576             if (counter%5==0) printf("\nA:\t%s%s\t",prefix.Data(),rd->GetName());
577           }
578         }
579         printf("\n");
580       }
581       //
582       // Basic array - dynamic length
583       //
584       if (dm->GetArrayDim()>0 && strlen(index) != 0){
585         //
586         // Dump first only for the moment
587         //  
588         printf("B:\t%s%s\t%s\n",prefix.Data(),rd->GetName(), dtype->AsString(pointer));
589       }
590     } else {
591     }
592   }
593 }  
594
595 //
596 // Small checks to test the TRealData and TDataType
597 //
598
599
600
601 void DumpDataSimple(){
602   //
603   // Dump example for elenatr data types 
604   //
605   TObject *obj = new TVectorD(20);
606   TClass * cl = obj->IsA();
607   if (!cl->GetListOfRealData()) cl->BuildRealData();
608   //
609   TRealData* rd = 0;
610   rd = (TRealData*)(cl->GetListOfRealData()->FindObject("fNrows"));
611   TDataMember* dm = rd->GetDataMember();
612   TDataType* dtype = dm->GetDataType();
613   //
614   Int_t offset = rd->GetThisOffset();
615   char* pointer = ((char*) obj) + offset;
616   printf("%s\n",dtype->AsString(pointer));
617 }
618
619 void DumpDataArray(){
620   //
621   // print array example
622   // 
623   TObject *obj = new TVectorD(20);
624   TClass * cl = obj->IsA();
625   if (!cl->GetListOfRealData()) cl->BuildRealData();
626   TRealData* rd = 0;
627   rd = (TRealData*)(cl->GetListOfRealData()->FindObject("*fElements"));
628   TDataMember* dm = rd->GetDataMember();
629   TDataType* dtype = dm->GetDataType();
630   dtype->Print();
631   //
632   Int_t offset = rd->GetThisOffset();
633   char* pointer = ((char*) obj) + offset; 
634   printf("%s\n",dtype->AsString(pointer));
635 }
636
637 void DumpTObjectArray(){
638   //
639   //
640   //
641   TObjArray *array = new TObjArray(10);
642   for (Int_t i=0; i<10; i++) array->AddLast(new TNamed(Form("n%d",i), Form("n%d",i)));  
643    AliOCDBtoolkit::DumpObjectRecursive(array);
644   //
645   //
646   TObject *obj = array;
647   TClass * cl = obj->IsA();
648   if (!cl->GetListOfRealData()) cl->BuildRealData();
649   TRealData* rd = 0;
650   rd = (TRealData*)(cl->GetListOfRealData()->FindObject("*fCont"));
651   TDataMember* dm = rd->GetDataMember();
652   TDataType* dtype = dm->GetDataType();
653   //
654   Int_t offset = rd->GetThisOffset();
655   char* pointer = ((char*) obj) + offset;
656   char** apointer = (char**) pointer;
657   //we have pointer to pointer here
658   TObject** ppobj = (TObject**) *apointer;
659   (*ppobj)->Print();
660   //
661   TIter myiter(array);
662   TObject  *arObject; 
663   dtype->Print();
664   while ((arObject = (TObject*)myiter.Next())) {
665     AliOCDBtoolkit::DumpObjectRecursive(arObject);
666   } 
667 }
668
669
670 Bool_t AliOCDBtoolkit::AddoptOCDBEntry( const char *finput, const char *output,  Int_t ustartRun, Int_t uendRun){
671   //
672   // Addopt OCDB entry - keeping all of the CDBentry quantities
673   // finput = "/cvmfs/alice.gsi.de/alice/simulation/2008/v4-15-Release/Residual/TPC/Calib/ClusterParam/Run127712_130850_v4_s0.root"
674   
675   TFile * fin = TFile::Open(finput);
676   if (!fin) return kFALSE;
677   AliCDBEntry * entry = (AliCDBEntry*) fin->Get("AliCDBEntry");
678   if (!entry) return kFALSE;
679   
680   AliCDBStorage* pocdbStorage = 0;
681   if (output!=0) AliCDBManager::Instance()->GetStorage(output);
682   else{
683     TString localStorage = "local://"+gSystem->GetFromPipe("pwd")+"/OCDB";
684     pocdbStorage = AliCDBManager::Instance()->GetStorage(localStorage.Data());
685   }
686   //
687   AliCDBId  idIn = entry->GetId();
688   AliCDBMetaData *metaDataIn = entry->GetMetaData();
689
690   AliCDBMetaData *metaData= new AliCDBMetaData();
691   metaData->SetObjectClassName(metaDataIn->GetObjectClassName());
692   metaData->SetResponsible(TString::Format("%s: copy",metaDataIn->GetResponsible()).Data());
693   metaData->SetBeamPeriod(metaDataIn->GetBeamPeriod());
694   //
695   metaData->SetAliRootVersion(metaDataIn->GetAliRootVersion()); //root version
696   metaData->SetComment((TString::Format("%s: copy",metaDataIn->GetComment()).Data()));
697   AliCDBId* id1=NULL;
698   id1=new AliCDBId(idIn.GetPath(), ustartRun, uendRun);
699   pocdbStorage->Put(entry->GetObject(), (*id1), metaData);
700   return kTRUE;
701 }