Fix for bug #74180: Commit and port changes to the release - AliFileMerger
[u/mrichter/AliRoot.git] / ANALYSIS / AliFileMerger.cxx
CommitLineData
623bb90b 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/* $Id$ */
17
18//////////////////////////////////////////////////////////////////////////
19// marian.ivanov@cern.ch
20// Utilities for file merging.
21// Additional functionality on top of the standard TFileMerger:
22//
23// 1. Possibility to Set the reject/accept list.
24// 1.a) Only entries selected in accept list are merged. By default all entries are selected
25// use AddAccept 0 to specify your desired entry
26// 1.b) Entries selected in reject list are not merged. By default the reject list is empty.
27//
28// 2. syswatch.log is created diring mergin procedure.
29// Memeory consumption - for reading and for merging can be monitored
30
31
32/*
33 Usage:
34 // Libraries for all classes to be merged should be loaded before using the class
35 gSystem->Load("libANALYSIS");
36 gSystem->Load("libANALYSIScalib");
37 gSystem->Load("libTPCcalib");
38 TH1::AddDirectory(0);
39
40 //Example usage starting from the input data list in text file:
41 //
42 AliFileMerger merger;
43 merger.AddReject("esdFriend");
44 merger.IterTXT("calib.list","CalibObjects.root",kFALSE);
45 //
46
47*/
48//////////////////////////////////////////////////////////////////////////
49
50
51#include <fstream>
52#include "TSystem.h"
53#include "TFile.h"
54#include "TGrid.h"
55#include "TGridResult.h"
56#include "TObjString.h"
57#include "TObjArray.h"
58#include "TMethodCall.h"
59
60#include "AliSysInfo.h"
61#include "AliFileMerger.h"
62
63ClassImp(AliFileMerger)
64
65////////////////////////////////////////////////////////////////////////
66
67AliFileMerger::AliFileMerger():
68 TNamed(),
69 fRejectMask(0),
70 fAcceptMask(0)
71{
72 //
73 // Default constructor
74 //
75}
76
77//______________________________________________________________________
78
79AliFileMerger::AliFileMerger(const char* name):
80 TNamed(name,name),
81 fRejectMask(0),
82 fAcceptMask(0)
83{
84 //
85 //
86 //
87}
88
89
90void AliFileMerger::IterAlien(const char* outputDir, const char* outputFileName, const char* pattern){
91
92 //
93 // Merge the files coming out of the calibration job
94 //
95
96 TObjArray * mergeArray= new TObjArray;
97
98 TString outputFile(outputFileName);
99 TString command;
100 // looking for files to be merged in the output directory
101 command = Form("find %s/ *%s", outputDir, pattern);
102 printf("command: %s\n", command.Data());
103 TGrid::Connect("alien://");
104 TGridResult *res = gGrid->Command(command);
105 if (!res) return;
106 TIter nextmap(res);
107 TMap *map = 0;
108 // loop over the results
109 while((map=(TMap*)nextmap())) {
110 // getting the turl
111 TObjString *objs = dynamic_cast<TObjString*>(map->GetValue("turl"));
112 if (!objs || !objs->GetString().Length()) {
113 // Nothing found - skip this output
114 delete res;
115 break;
116 }
117 printf("looking for file %s\n",(objs->GetString()).Data());
118 TFile* currentFile=TFile::Open((objs->GetString()).Data());
f8f4c15e 119 if(!currentFile) continue; // protection
623bb90b 120 Merge(currentFile, mergeArray);
3fd30500 121
122 if(currentFile) delete currentFile;
623bb90b 123 }
124 Bool_t separate = kFALSE;
f8f4c15e 125 if (separate) {
623bb90b 126 StoreSeparateResults(mergeArray,outputFileName);
f8f4c15e 127 }
128 else {
623bb90b 129 StoreResults(mergeArray,outputFileName);
f8f4c15e 130 }
623bb90b 131 delete mergeArray;
f8f4c15e 132 delete res;
3fd30500 133
623bb90b 134}
135
136
137
138void AliFileMerger::IterTXT( const char * fileList, const char* outputFileName, Bool_t separate){
139
140 // Merge the files indicated in the list - fileList
141 // ASCII file option example:
142 // find `pwd`/ | grep AliESDfriends_v1.root > calib.list
143
144 TObjArray * mergeArray= new TObjArray;
145
146 // Open the input stream
147
148 ifstream in;
149 in.open(fileList);
150 // Read the input list of files
151 TString objfile;
152 Int_t counter=0;
153 while(in.good()) {
154 in >> objfile;
155 if (!objfile.Contains("root")) continue; // protection
156 printf("Open file:Counter\t%d\tMerging file %s\n",counter++,objfile.Data());
157 TFile currentFile(objfile.Data());
158 Merge(&currentFile, mergeArray);
159 }
f8f4c15e 160 if (separate) {
623bb90b 161 StoreSeparateResults(mergeArray, outputFileName);
f8f4c15e 162 }
163 else {
623bb90b 164 StoreResults(mergeArray, outputFileName);
f8f4c15e 165 }
166
623bb90b 167 delete mergeArray;
168}
169
170void AliFileMerger::StoreResults(TObjArray * array, const char* outputFileName){
171 //
172 // Storing the results in one single file
173 //
174 TFile *f = new TFile(outputFileName,"recreate");
175 for (Int_t i=0; i<array->GetEntries(); i++){
176 TObject *object0 = array->At(i);
177 if (!object0) continue;
178 object0->Write();
179 }
180 f->Close();
181 delete f;
182}
183
184
185void AliFileMerger::StoreSeparateResults(TObjArray * array, const char* outputFileName){
186 //
187 // Store the results in separate files (one per object)
188 //
189 for (Int_t i=0; i<array->GetEntries(); i++){
190 TObject *object0 = array->At(i);
191 if (!object0) continue;
192 TFile *f = new TFile(Form("%s_%s.root",outputFileName,object0->GetName()),"recreate");
193 object0->Write();
194 f->Close();
195 delete f;
196 }
197}
198
199
200
201void AliFileMerger::Merge(TFile* fileIn, TObjArray * array){
202 //
203 // Merging procedure
204 //
205 static Int_t counter=-1;
206 counter++;
207 TObjArray *carray = new TObjArray; //array of the objects inside current file
208 carray->SetOwner(kTRUE);
209
210 // load all objects to memory
211
212 TList *farr = fileIn->GetListOfKeys();
f8f4c15e 213 if (!farr) {
214 delete carray;
215 return;
216 }
623bb90b 217 for (Int_t ical=0; ical<farr->GetEntries(); ical++){
218 if (!farr->At(ical)) continue;
219 TString name(farr->At(ical)->GetName());
220 if (!IsAccepted(name)) continue; // skip not accepted entries
221 TObject *obj = fileIn->Get(name.Data());
222 if (obj) carray->AddLast(obj);
223 AliSysInfo::AddStamp(name.Data(),1,ical,counter);
224 }
225
f8f4c15e 226 if (carray->GetEntries()==0) {
227 delete carray;
228 return;
229 }
623bb90b 230 TMethodCall callEnv;
231
232 for (Int_t i=0; i<carray->GetEntries(); i++){
233
234 TObjArray *templist = new TObjArray(1);
235 templist->SetOwner(kFALSE);
236 TObject *currentObject = carray->At(i);
f8f4c15e 237 if (!currentObject) {
238 delete templist;
239 continue;
240 }
623bb90b 241 printf("%s\n",currentObject->GetName());
242 callEnv.InitWithPrototype(currentObject->IsA(), "Merge", "TCollection*");
f8f4c15e 243 if (!callEnv.IsValid()) {
244 delete templist;
245 continue;
246 }
623bb90b 247 TString oname=currentObject->GetName();
248 TObject *mergedObject = array->FindObject(currentObject->GetName());
249 if (!mergedObject) {
250 array->AddLast(currentObject);
251 carray->RemoveAt(i);
f8f4c15e 252 delete templist;
623bb90b 253 continue;
254 }
255 templist->AddLast(currentObject);
256 callEnv.SetParam((Long_t) templist);
257 callEnv.Execute(mergedObject);
258 AliSysInfo::AddStamp(currentObject->GetName(),2,i,counter);
259 delete templist;
260 }
261 delete carray;
262}
263
264Bool_t AliFileMerger::IsAccepted(TString name){
265 //
266 // Accept/reject logic
267 // name - name of the entry
268 //
269 // if fAcceptMask specified - entry has to be in list of selected
270 // if fRejectMask speciefied - entry with name speciief in the list are rejected
271 //
272 Bool_t accept=kTRUE;
273 if (fAcceptMask){
274 //
275 accept=kFALSE;
276 for (Int_t iaccept=0; iaccept<fAcceptMask->GetEntries(); iaccept++){
277 if (name.Contains(fAcceptMask->At(iaccept)->GetName())) accept=kTRUE; // entry was selected
278 }
279 }
280 if (!accept) return kFALSE;
281
282 if (fRejectMask){
283 //
284 for (Int_t ireject=0; ireject<fRejectMask->GetEntries(); ireject++){
285 if (name.Contains(fRejectMask->At(ireject)->GetName())) accept=kFALSE; // entry was rejected
286 }
287 }
288 return accept;
289}
290
291
292
293
294void AliFileMerger::AddReject(const char *reject){
295 //
296 // add reject string to the list of entries to be rejected for merging
297 //
298 if (!fRejectMask) fRejectMask = new TObjArray;
299 fRejectMask->AddLast(new TObjString(reject));
300}
301void AliFileMerger::AddAccept(const char *accept){
302 //
303 // add reject string to the list of entries to be rejected for merging
304 //
305 if (!fAcceptMask) fAcceptMask = new TObjArray;
306 fAcceptMask->AddLast(new TObjString(accept));
307
308
309}
310