]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - ANALYSIS/AliTagAnalysis.cxx
Small fix in view of reconstruction without SDD (A.Dainese)
[u/mrichter/AliRoot.git] / ANALYSIS / AliTagAnalysis.cxx
index c9c1aa0b920db89a49bdac43248b9caa095ca2f8..77bd1081ac493549e1c67537feea4d490b8381d2 100644 (file)
@@ -27,6 +27,7 @@
 #include <TEventList.h>
 #include <TEntryList.h>
 #include <TTreeFormula.h>
+#include <TMap.h>
 
 //ROOT-AliEn
 #include <TGridResult.h>
@@ -77,22 +78,26 @@ AliTagAnalysis::~AliTagAnalysis() {
 }
 
 //___________________________________________________________________________
-Bool_t  AliTagAnalysis::AddTagsFile(const char *alienUrl) {
-  // Add a single tags file to the chain
-
-  Bool_t rv = kTRUE ;
-
-  if (! fChain) fChain = new TChain("T");
-
-  TFile *f = TFile::Open(alienUrl,"READ");
-  fChain->Add(alienUrl);
-  AliInfo(Form("Chained tag files: %d ",fChain->GetEntries()));
-  delete f;
+Bool_t  
+AliTagAnalysis::AddTagsFile(const char* alienUrl, Bool_t checkFile) 
+{
+  /// Add a single tags file to the chain
+  ///
+  /// If checkFile=kTRUE (default) the file is opened to check
+  /// it can be and that it contains data.
+  /// It's safer but a lot longer...
+  
+  if (!fChain) fChain = new TChain("T");
 
-  if (fChain->GetEntries() == 0 )
-    rv = kFALSE ;
+  if ( checkFile )
+  {
+    return ( fChain->AddFile(alienUrl,-1) > 0 );
+  }
+  else
+  {
+    return ( fChain->AddFile(alienUrl) > 0 );
+  }
 
-  return rv ;
 }
 
 //___________________________________________________________________________
@@ -113,7 +118,7 @@ void AliTagAnalysis::ChainLocalTags(const char *dirname) {
   const char * name = 0x0;
   // Add all files matching *pattern* to the chain
   while((name = gSystem->GetDirEntry(dirp))) {
-    if (strstr(name,tagPattern)) { 
+    if (tagPattern && strstr(name,tagPattern)) { 
       fTagFilename = fTagDirName;
       fTagFilename += "/";
       fTagFilename += name;
@@ -123,7 +128,8 @@ void AliTagAnalysis::ChainLocalTags(const char *dirname) {
       
     }//pattern check
   }//directory loop
-  AliInfo(Form("Chained tag files: %d ",fChain->GetEntries()));
+  //AliInfo(Form("Chained tag files: %d ",fChain->GetEntries()));
+ // AliDebug(Form("Chained tag files: %d ",fChain->GetEntries()));
   fChain->ls();
   
 }
@@ -132,7 +138,7 @@ void AliTagAnalysis::ChainLocalTags(const char *dirname) {
 //___________________________________________________________________________
 TChain * AliTagAnalysis::ChainGridTags(TGridResult *res) {
   //Loops overs the entries of the TGridResult
-  //Chains the tags that are stored in the GRID
+   //Chains the tags that are stored in the GRID
   ftagresult = res;
   Int_t nEntries = ftagresult->GetEntries();
  
@@ -159,13 +165,9 @@ TChain *AliTagAnalysis::QueryTags(AliRunTagCuts *runTagCuts,
   //and returns a TChain along with the associated TEventList
   AliInfo(Form("Querying the tags........"));
 
-  Bool_t aod = kFALSE;
   TString aliceFile;
   if(fAnalysisType == "ESD") aliceFile = "esdTree";
-  else if(fAnalysisType == "AOD") {
-      aliceFile = "aodTree";
-      aod = kTRUE;
-  }
+  else if(fAnalysisType == "AOD") aliceFile = "aodTree";
   else AliFatal("Only ESD and AOD type is implemented!!!");
 
   //ESD file chain
@@ -175,69 +177,68 @@ TChain *AliTagAnalysis::QueryTags(AliRunTagCuts *runTagCuts,
   
   //Defining tag objects
   AliRunTag   *tag     = new AliRunTag;
-  AliEventTag *evTag   = new AliEventTag;
+  //  AliEventTag *evTag   = 0x0;
+  AliFileTag  *flTag   = 0x0;
+
   fChain->SetBranchAddress("AliTAG",&tag);
 
   TString guid;
   TString turl;
   TString path;
 
-  TTree*      cTree     = 0; 
   TEntryList* localList = new TEntryList();
 
   Int_t iAccepted = 0;
-  Int_t iev       = 0;
-  Int_t ientry    = 0;
-  Int_t cEntries  = 0;
   
-  for(Int_t iTagFiles = 0; iTagFiles < fChain->GetEntries(); iTagFiles++) {
-    fChain->GetEntry(iTagFiles);
-    TTree* tree = fChain->GetTree();
-    if (cTree != tree) {
-       // Fix for aod tags: for each tree in the chain, merge the entries
-       cTree    = tree;
-       cEntries = tree->GetEntries();
-       iev      = 0;
-       ientry   = 0;
-    }
+  for(Int_t iEntry = 0; iEntry < fChain->GetEntries(); iEntry++) {
+    fChain->GetEntry(iEntry);
+    evTagCuts->InitializeTriggerClasses(tag->GetActiveTriggerClasses());
 
     if(runTagCuts->IsAccepted(tag)) {
       if(lhcTagCuts->IsAccepted(tag->GetLHCTag())) {
        if(detTagCuts->IsAccepted(tag->GetDetectorTags())) {
-         if ((iev == 0) || !aod) localList->Reset();
+         localList->Reset();
          Int_t iEvents = tag->GetNEvents();
-         const TClonesArray *tagList = tag->GetEventTags();
-         for(Int_t i = 0; i < iEvents; i++) {
-           evTag = (AliEventTag *) tagList->At(i);
-           guid = evTag->GetGUID(); 
-           turl = evTag->GetTURL(); 
-           path = evTag->GetPath();
-           localList->SetTreeName(aliceFile.Data());
-           if(turl!="") localList->SetFileName(turl.Data());
-           else localList->SetFileName(path.Data());
-
-           if(evTagCuts->IsAccepted(evTag)) {
-               if(aod) localList->Enter(iev);
-               else localList->Enter(i);
-           }
-           iev++;
-         }//event loop
-         if ((ientry == cEntries-1) || !aod) {
-             iAccepted += localList->GetN();
-             if(path != "") esdChain->AddFile(path);
-             else if(turl != "") esdChain->AddFile(turl);
-             fGlobalList->Add(localList);
+         
+         for (int i = 0; i < iEvents; i++) {
+           //      evTag = tag->GetEventTag(i);
+           flTag = tag->GetFileTagForEvent(i);
+           guid = flTag->GetGUID();
+           turl = flTag->GetTURL();
+           path = flTag->GetPath();
+           localList->SetTreeName(aliceFile.Data());
+           if(turl!="") localList->SetFileName(turl.Data());
+           else localList->SetFileName(path.Data());
+
+           if(evTagCuts->IsAccepted(tag->GetEventTag(i))) localList->Enter(i);
          }
+
+//       const TClonesArray *tagList = tag->GetEventTags();
+//       for(Int_t i = 0; i < iEvents; i++) {
+//         evTag = (AliEventTag *) tagList->At(i);
+//         guid = evTag->GetGUID(); 
+//         turl = evTag->GetTURL(); 
+//         path = evTag->GetPath();
+//         localList->SetTreeName(aliceFile.Data());
+//         if(turl!="") localList->SetFileName(turl.Data());
+//         else localList->SetFileName(path.Data());
+           
+//         if(evTagCuts->IsAccepted(evTag)) localList->Enter(i);
+//       }//event loop
+         iAccepted += localList->GetN();
+         if(turl != "")      esdChain->AddFile(turl);
+         else if(path != "") esdChain->AddFile(path);
+         fGlobalList->Add(localList);
        }//detector tag cuts
       }//lhc tag cuts
     }//run tags cut
     tag->Clear();
-    ientry++;
   }//tag file loop
-  AliInfo(Form("Accepted events: %d",iAccepted));
+  AliInfo(Form("Accepted events: %d", iAccepted));
   esdChain->ls();
   esdChain->SetEntryList(fGlobalList,"ne");
   delete tag;
+  delete localList;
   
   return esdChain;
 }
@@ -251,16 +252,13 @@ TChain *AliTagAnalysis::QueryTags(const char *fRunCut,
   //event tag cuts from the AliEventTagCuts object      
   //and returns a TChain along with the associated TEventList   
   AliInfo(Form("Querying the tags........"));   
-  
-  Bool_t aod = kFALSE;
+
   TString aliceFile;
   if(fAnalysisType == "ESD") aliceFile = "esdTree";
-  else if(fAnalysisType == "AOD") {
-      aliceFile = "aodTree";
-      aod = kTRUE;
-  }
+  else if(fAnalysisType == "AOD") aliceFile = "aodTree";
   else AliFatal("Only ESD and AOD type is implemented!!!");
 
+
   //ESD file chain
   TChain *esdChain = new TChain(aliceFile.Data());
   //global entry list
@@ -268,7 +266,7 @@ TChain *AliTagAnalysis::QueryTags(const char *fRunCut,
   
   //Defining tag objects        
   AliRunTag   *tag   = new AliRunTag;   
-  AliEventTag *evTag = new AliEventTag;         
+  //  AliEventTag *evTag = 0x0;
   fChain->SetBranchAddress("AliTAG",&tag);      
   
   TString guid;         
@@ -282,12 +280,9 @@ TChain *AliTagAnalysis::QueryTags(const char *fRunCut,
   
   TEntryList* localList = new TEntryList();
 
-  Int_t iev       = 0;
-  Int_t ientry    = 0;
-  Int_t cEntries  = 0;
-  Int_t current   = -1;         
+  Int_t current = -1; 
   Int_t iAccepted = 0;          
-
+  
   for(Int_t iTagFiles = 0; iTagFiles < fChain->GetEntries(); iTagFiles++) {
     fChain->GetEntry(iTagFiles);        
     if (current != fChain->GetTreeNumber()) {   
@@ -295,129 +290,183 @@ TChain *AliTagAnalysis::QueryTags(const char *fRunCut,
       fLHCFormula->UpdateFormulaLeaves();       
       fDetectorFormula->UpdateFormulaLeaves();          
       fEventFormula->UpdateFormulaLeaves();     
-      // Fix for aod tags: for each tree in the chain, merge the entries
-      cEntries = (fChain->GetTree())->GetEntries();
-      iev      = 0;
-      ientry   = 0;
-      //
       current = fChain->GetTreeNumber();        
     }   
+    
     if(fRunFormula->EvalInstance(iTagFiles) == 1) {     
       if(fLHCFormula->EvalInstance(iTagFiles) == 1) {   
        if(fDetectorFormula->EvalInstance(iTagFiles) == 1) {
-          if ((iev == 0) || !aod) localList->Reset();   
-         Int_t iEvents = fEventFormula->GetNdata();     
-         const TClonesArray *tagList = tag->GetEventTags();     
-         for(Int_t i = 0; i < iEvents; i++) {   
-           evTag = (AliEventTag *) tagList->At(i);      
-           guid = evTag->GetGUID();     
-           turl = evTag->GetTURL();     
-           path = evTag->GetPath();     
-           localList->SetTreeName(aliceFile.Data());
-           localList->SetFileName(turl.Data());
-           if(fEventFormula->EvalInstance(i) == 1) {
-               if(aod) localList->Enter(iev);
-               else localList->Enter(i);
-           }
-           iev++;
-         }//event loop          
-
-         if ((ientry == cEntries-1) || !aod) {  
-             if(path != "") esdChain->AddFile(path);    
-             else if(turl != "") esdChain->AddFile(turl);       
-             fGlobalList->Add(localList);
-             iAccepted += localList->GetN();
-         }
+          localList->Reset();   
+         //      Int_t iEvents = fEventFormula->GetNdata();     
+         // *** FIXME ***
+
+//       const TClonesArray *tagList = tag->GetEventTags();     
+//       for(Int_t i = 0; i < iEvents; i++) {   
+//         evTag = (AliEventTag *) tagList->At(i);      
+//         guid = evTag->GetGUID();     
+//         turl = evTag->GetTURL();     
+//         path = evTag->GetPath();     
+//         localList->SetTreeName(aliceFile.Data());
+//         localList->SetFileName(turl.Data());
+//         if(fEventFormula->EvalInstance(i) == 1) localList->Enter(i);
+//       }//event loop          
+
+         if(path != "")      esdChain->AddFile(path);   
+         else if(turl != "") esdChain->AddFile(turl);   
+         fGlobalList->Add(localList);
+         iAccepted += localList->GetN();
        }//detector tag cuts
       }//lhc tag cuts
     }//run tag cut      
     tag->Clear();
-    ientry++;
   }//tag file loop      
-  AliInfo(Form("Accepted events: %d",iAccepted));       
+  AliInfo(Form("Accepted events: %d", iAccepted));      
   esdChain->SetEntryList(fGlobalList,"ne");     
 
   delete tag;
+  delete localList;
   return esdChain;      
 }
 
 //___________________________________________________________________________
-Bool_t AliTagAnalysis::CreateXMLCollection(const char* name, 
-                                          AliRunTagCuts *runTagCuts, 
-                                          AliLHCTagCuts *lhcTagCuts, 
-                                          AliDetectorTagCuts *detTagCuts, 
-                                          AliEventTagCuts *evTagCuts) {
-  //Queries the tag chain using the defined 
-  //event tag cuts from the AliEventTagCuts object
-  //and returns a XML collection
+Bool_t 
+AliTagAnalysis::CreateXMLCollection(const char* name, 
+                                    AliRunTagCuts *runTagCuts, 
+                                    AliLHCTagCuts *lhcTagCuts, 
+                                    AliDetectorTagCuts *detTagCuts, 
+                                    AliEventTagCuts *evTagCuts) 
+{
+  /// Queries the tag chain using the defined run, lhc, detector and event tag objects
+  /// and create a XML collection named "name.xml"
+  /// if any of the runTagCuts, lhcTagCuts, detTagCuts or evTagCuts is NULL
+  /// check on that object will be skipped.
+  
   AliInfo(Form("Creating the collection........"));
-
-  Bool_t aod = kFALSE;
-  if(fAnalysisType == "AOD") aod = kTRUE;
-
-
-  AliXMLCollection *collection = new AliXMLCollection();
-  collection->SetCollectionName(name);
-  collection->WriteHeader();
-
+  
+  if (!fChain) 
+  {
+    AliError("fChain is NULL. Cannot make a collection from that !");
+    return kFALSE;
+  }
+  
+  AliXMLCollection collection;
+  collection.SetCollectionName(name);
+  collection.WriteHeader();
+  
   TString guid;
   TString turl;
   TString lfn;
   
-  TTree*      cTree = 0; 
-  TEntryList* localList = new TEntryList();
+  TEntryList localList;
   Int_t iAccepted = 0;
-  Int_t iev       = 0;
-  Int_t ientry    = 0;
-  Int_t cEntries  = 0;
-
+    
+  Int_t iRejectedRun = 0;
+  Int_t iRejectedLHC = 0;
+  Int_t iRejectedDet = 0;
+  Int_t iRejectedEvt = 0;
+  
+  Int_t iTotalEvents = 0;
+  
+  Int_t iAcceptedEvtInFile = 0;
+  Int_t iRejectedEvtInFile = 0;
+  
   //Defining tag objects
-  AliRunTag   *tag   = new AliRunTag;
-  AliEventTag *evTag = new AliEventTag;
+  AliRunTag* tag = new AliRunTag;
   fChain->SetBranchAddress("AliTAG",&tag);
 
-  for(Int_t iTagFiles = 0; iTagFiles < fChain->GetEntries(); iTagFiles++) {
+  Int_t iTagFiles = 0;
+  
+  //  AliEventTag *evTag = 0x0;
+  AliFileTag  *flTag = 0x0;
 
-    fChain->GetEntry(iTagFiles);
-    TTree* tree = fChain->GetTree();
-    if (cTree != tree) {
-       // Fix for aod tags: for each tree in the chain, merge the entries
-       cTree    = tree;
-       cEntries = tree->GetEntries();
-       iev      = 0;
-       ientry   = 0;
-    }
+  //  for(Int_t iTagFiles = 0; iTagFiles < fChain->GetListOfFiles()->GetEntries(); ++iTagFiles) 
+  for(Int_t iRunTags = 0; iRunTags < fChain->GetEntries(); ++iRunTags) 
+  {
+    fChain->GetEntry(iRunTags);
     //Event list
-    if ((iev == 0) || !aod) localList->Reset();
-    if(runTagCuts->IsAccepted(tag)) {
-      if(lhcTagCuts->IsAccepted(tag->GetLHCTag())) {
-       if(detTagCuts->IsAccepted(tag->GetDetectorTags())) {
-         Int_t iEvents = tag->GetNEvents();
-         const TClonesArray *tagList = tag->GetEventTags();
-         for(Int_t i = 0; i < iEvents; i++) {
-           evTag = (AliEventTag *) tagList->At(i);
-           guid = evTag->GetGUID(); 
-           turl = evTag->GetTURL(); 
-           lfn = turl(8,turl.Length());
-           if(evTagCuts->IsAccepted(evTag)) {
-               if(aod) localList->Enter(iev);
-               else localList->Enter(i);
+    iTotalEvents += tag->GetNEvents();
+    localList.Reset();
+    
+    evTagCuts->InitializeTriggerClasses(tag->GetActiveTriggerClasses());
+    
+    if ( !runTagCuts || ( runTagCuts && runTagCuts->IsAccepted(tag) ) ) 
+      {
+       if ( !lhcTagCuts || ( lhcTagCuts && lhcTagCuts->IsAccepted(tag->GetLHCTag())) ) 
+         {
+           if ( !detTagCuts || ( detTagCuts && detTagCuts->IsAccepted(tag->GetDetectorTags())) )
+             {
+               for (int iChunk = 0; iChunk < tag->GetNFiles(); iChunk++, iTagFiles++) 
+                 {
+                   iRejectedEvtInFile = 0;
+                   iAcceptedEvtInFile = 0;
+
+                   localList.Reset();
+                   
+                   flTag = tag->GetFileTag(iChunk);
+                   guid = flTag->GetGUID();
+                   turl = flTag->GetTURL();
+                   lfn = turl(8,turl.Length());
+                   
+                   for (int i = 0; i<flTag->GetNEvents(); i++) 
+                     {
+                       //                      evTag = flTag->GetEventTag(i);
+                       
+                       if( !evTagCuts || ( evTagCuts && evTagCuts->IsAccepted(flTag->GetEventTag(i))) )
+                         {
+                           localList.Enter(i);
+                           iAcceptedEvtInFile++;
+                         }
+                       else 
+                         {
+                           ++iRejectedEvt;
+                           ++iRejectedEvtInFile;
+                         }
+                     }
+                   // *** FIXME ***
+//             Int_t i(0);
+
+//             TIter next(tag->GetEventTags());
+//             AliEventTag* evTag(0x0);
+//             iRejectedEvtInFile = 0;
+//             iAcceptedEvtInFile = 0;
+//             while ( ( evTag = static_cast<AliEventTag*>(next()) ) )
+//               {
+//                 guid = evTag->GetGUID(); 
+//                 turl = evTag->GetTURL(); 
+//                 lfn = turl(8,turl.Length());
+//                 if( !evTagCuts || ( evTagCuts && evTagCuts->IsAccepted(evTag)) )
+//                   {
+//                     localList.Enter(i);
+//                     iAcceptedEvtInFile++;
+//                   }
+//                 else 
+//                   {
+//                     ++iRejectedEvt;
+//                     ++iRejectedEvtInFile;
+//                   }
+//                 ++i;
+//               }//event loop
+                   iAccepted += localList.GetN();
+                   collection.WriteBody(iTagFiles+1,guid,lfn,turl,&localList,iAcceptedEvtInFile,iRejectedEvtInFile);
+                 } // chunk loop
+             }//detector tag cuts
+           else {
+             iRejectedDet += tag->GetNEvents();
            }
-           iev++;
-         }//event loop
-         if ((ientry == cEntries-1) || !aod) {
-             collection->WriteBody(iTagFiles+1,guid,lfn,turl,localList);
-             iAccepted += localList->GetN();
-         }
-       }//detector tag cuts
-      }//lhc tag cuts 
-    }//run tag cuts
+         }//lhc tag cuts 
+       else {
+         iRejectedLHC += tag->GetNEvents();
+       }
+      }//run tag cuts
+    else {
+      iRejectedRun += tag->GetNEvents();
+    }
     tag->Clear();
-    ientry++;
-  }//tag file loop
-  collection->Export();
+  } //tag file loop
+  
+  collection.WriteSummary(iTotalEvents, iAccepted, iRejectedRun, iRejectedLHC, iRejectedDet, iRejectedEvt);
+  collection.Export();
   
-  delete tag;
   return kTRUE;
 }
 
@@ -432,8 +481,6 @@ Bool_t AliTagAnalysis::CreateXMLCollection(const char* name,
   //and returns a XML collection
   AliInfo(Form("Creating the collection........"));
 
-  Bool_t aod = kFALSE;
-  if(fAnalysisType == "AOD") aod = kTRUE;
 
   AliXMLCollection *collection = new AliXMLCollection();
   collection->SetCollectionName(name);
@@ -444,23 +491,30 @@ Bool_t AliTagAnalysis::CreateXMLCollection(const char* name,
   TString lfn;
   TEntryList* localList = new TEntryList();
   
-
   Int_t iAccepted = 0;
-  Int_t iev       = 0;
-  Int_t ientry    = 0;
-  Int_t cEntries  = 0;
+
+  Int_t iRejectedRun = 0;
+  Int_t iRejectedLHC = 0;
+  Int_t iRejectedDet = 0;
+  Int_t iRejectedEvt = 0;
+
+  Int_t iTotalEvents = 0;
+
+  Int_t iAcceptedEvtInFile = 0;
+  Int_t iRejectedEvtInFile = 0;
 
   //Defining tag objects
   AliRunTag *tag     = new AliRunTag;
-  AliEventTag *evTag = new AliEventTag;
+  //  AliEventTag *evTag = 0x0;
   fChain->SetBranchAddress("AliTAG",&tag);
 
   TTreeFormula *fRunFormula = new TTreeFormula("fRun",fRunCut,fChain);
   TTreeFormula *fLHCFormula = new TTreeFormula("fLHC",fLHCCut,fChain);          
   TTreeFormula *fDetectorFormula = new TTreeFormula("fDetector",fDetectorCut,fChain);
   TTreeFormula *fEventFormula = new TTreeFormula("fEvent",fEventCut,fChain);
-
+  
   Int_t current = -1;
+
   for(Int_t iTagFiles = 0; iTagFiles < fChain->GetEntries(); iTagFiles++) {
 
     fChain->GetEntry(iTagFiles);
@@ -469,42 +523,55 @@ Bool_t AliTagAnalysis::CreateXMLCollection(const char* name,
       fLHCFormula->UpdateFormulaLeaves();
       fDetectorFormula->UpdateFormulaLeaves();
       fEventFormula->UpdateFormulaLeaves();
-      // Fix for aod tags: for each tree in the chain, merge the entries
-      cEntries = (fChain->GetTree())->GetEntries();
-      iev      = 0;
-      ientry   = 0;
-      //
       current = fChain->GetTreeNumber();
-    }
-    //Event list
-    if ((iev == 0) || !aod) localList->Reset();
+     }
+   //Event list
+    iTotalEvents += tag->GetNEvents();
+    localList->Reset();
     if(fRunFormula->EvalInstance(iTagFiles) == 1) {
       if(fLHCFormula->EvalInstance(iTagFiles) == 1) {   
        if(fDetectorFormula->EvalInstance(iTagFiles) == 1) {     
-         Int_t iEvents = fEventFormula->GetNdata();
-         const TClonesArray *tagList = tag->GetEventTags();
-         for(Int_t i = 0; i < iEvents; i++) {
-           evTag = (AliEventTag *) tagList->At(i);
-           guid = evTag->GetGUID(); 
-           turl = evTag->GetTURL(); 
-           lfn = turl(8,turl.Length());
-           if(fEventFormula->EvalInstance(i) == 1) {
-               if(aod) localList->Enter(iev);
-               else localList->Enter(i);
-           }
-           iev++;
-         }//event loop
-         if ((ientry == cEntries-1) || !aod) {
-             collection->WriteBody(iTagFiles+1,guid,lfn,turl,localList);
-             iAccepted += localList->GetN();
-         }
+         //      Int_t iEvents = fEventFormula->GetNdata();
+         // *** FIXME ***
+
+
+//       const TClonesArray *tagList = tag->GetEventTags();
+//       iRejectedEvtInFile = 0;
+//       iAcceptedEvtInFile = 0;
+//       for(Int_t i = 0; i < iEvents; i++) {
+//         evTag = (AliEventTag *) tagList->At(i);
+//         guid = evTag->GetGUID(); 
+//         turl = evTag->GetTURL(); 
+//         lfn = turl(8,turl.Length());
+//         if(fEventFormula->EvalInstance(i) == 1) {
+//           localList->Enter(i);
+//           iAcceptedEvtInFile++;
+//         }
+//         else {
+//           iRejectedEvt++;
+//           iRejectedEvtInFile++;
+//         }
+//       }//event loop
+
+         collection->WriteBody(iTagFiles+1,guid,lfn,turl,localList,iAcceptedEvtInFile, iRejectedEvtInFile);
+         iAccepted += localList->GetN();
        }//detector tag cuts
+       else {
+         iRejectedDet += tag->GetNEvents();
+       }
       }//lhc tag cuts 
+      else {
+       iRejectedLHC += tag->GetNEvents();
+      }
     }//run tag cuts
-    ientry++;
+    else {
+      iRejectedRun += tag->GetNEvents();
+    }
   }//tag file loop
+  collection->WriteSummary(iTotalEvents, iAccepted, iRejectedRun, iRejectedLHC, iRejectedDet, iRejectedEvt);
   collection->Export();
-
+  
   delete tag;
   return kTRUE;
 }
@@ -529,7 +596,7 @@ TChain *AliTagAnalysis::GetInputChain(const char* system, const char *wn) {
   collection->Reset();
   while (collection->Next()) {
     AliInfo(Form("Adding: %s",collection->GetTURL("")));
-    fAnalysisChain->Add(collection->GetTURL(""));
+    if (fAnalysisChain) fAnalysisChain->Add(collection->GetTURL(""));
     TEntryList *list = (TEntryList *)collection->GetEventList("");
     for(Int_t i = 0; i < list->GetN(); i++) fEventList->Enter(iAccepted+list->GetEntry(i));
 
@@ -537,7 +604,7 @@ TChain *AliTagAnalysis::GetInputChain(const char* system, const char *wn) {
     else if(fsystem == "PbPb") iAccepted += 1;
   }
 
-  fAnalysisChain->SetEventList(fEventList);
+  if (fAnalysisChain) fAnalysisChain->SetEventList(fEventList);
   
   AliInfo(Form("Number of selected events: %d",fEventList->GetN()));
 
@@ -545,34 +612,91 @@ TChain *AliTagAnalysis::GetInputChain(const char* system, const char *wn) {
 }
 
 //___________________________________________________________________________
-TChain *AliTagAnalysis::GetChainFromCollection(const char* collectionname, 
-                                              const char* treename) {
-  //returns the TChain+TEntryList object- used in batch sessions
-  TString aliceFile = treename;
-  Int_t iAccepted = 0;
-  TChain *fAnalysisChain = 0;
-  if(aliceFile == "esdTree") fAnalysisChain = new TChain("esdTree");
-  else if(aliceFile == "aodTree") fAnalysisChain = new TChain("aodTree");
-  else AliFatal("Inconsistent tree name - use esdTree or aodTree!");
+TChain*
+AliTagAnalysis::CreateChainFromCollection(const char* collectionname, const char* treename)
+{
+  /// Build a TChain (with its TEntryList object attached) from an XML collection.
+  /// Returned chain must be deleted by the client.
+
+  TString streename(treename);
+  if ( streename != "esdTree" && streename != "aodTree" )
+  {
+    AliErrorClass("Only esdTree and aodTree implemented so far...");
+    return 0x0;
+  }
+  
+  TChain* chain = new TChain(streename.Data());
 
-  //Event list
-  fGlobalList = new TEntryList();
-  AliXMLCollection *collection = AliXMLCollection::Open(collectionname);
+  // create the event list for the chain. Will be attached to the chain
+  // which thus becomes the owner of it.
+  TEntryList* elist = new TEntryList; 
+  
+  AliXMLCollection* collection = AliXMLCollection::Open(collectionname);
+
+  // Tag selection summary per file
+  TMap* tagCutSummary = new TMap();
+  tagCutSummary->SetName("TagCutSumm");
 
+  Int_t iAccepted = 0;
+  
   collection->Reset();
-  while (collection->Next()) {
-    AliInfo(Form("Adding: %s",collection->GetTURL("")));
-    fAnalysisChain->Add(collection->GetTURL(""));
-    TEntryList *list = (TEntryList *)collection->GetEventList("");
-    list->SetTreeName(aliceFile.Data());
+  
+  while (collection->Next()) 
+  {
+    AliDebugClass(1,Form("Adding: %s",collection->GetTURL("")));
+    chain->Add(collection->GetTURL(""));
+    TEntryList *list = collection->GetEventList("");
+    list->SetTreeName(streename.Data());
     list->SetFileName(collection->GetTURL(""));
-    fGlobalList->Add(list);
+    elist->Add(list);
     iAccepted += list->GetN();
+    if (collection->GetCutSumm())
+    {
+      tagCutSummary->Add(new TObjString(collection->GetTURL("")), new TObjString(collection->GetCutSumm()));
+    }
   }
 
-  fAnalysisChain->SetEntryList(fGlobalList,"ne");
+  chain->SetEntryList(elist,"ne"); // ne => do not expand tree name and/or file names
   
-  AliInfo(Form("Number of selected events: %d",iAccepted));
+  AliDebugClass(1,Form("Number of selected events: %d",iAccepted));
 
-  return fAnalysisChain;
+  TList *aUserInfo = chain->GetUserInfo();
+  aUserInfo->Add(tagCutSummary);
+
+  Int_t iAccEv;
+  Int_t iTotalEvents;
+  Int_t iRejRun;
+  Int_t iRejLHC;
+  Int_t iRejDet;
+  Int_t iRejEvt;
+
+  collection->GetCollectionSummary(&iTotalEvents, &iAccEv, &iRejRun, &iRejLHC, &iRejDet, &iRejEvt);
+  char nstr[2000];
+
+  snprintf(nstr, 2000, "TotalEvents=%i", iTotalEvents);
+  TObjString *iTotStr = new TObjString(nstr);
+  aUserInfo->Add(iTotStr);
+
+  snprintf(nstr, 2000, "AcceptedEvents=%i", iAccepted);
+  TObjString *iAccStr = new TObjString(nstr);
+  aUserInfo->Add(iAccStr);
+
+  snprintf(nstr, 2000, "RejectedRun=%i", iRejRun);
+  TObjString *iRejRunStr = new TObjString(nstr);
+  aUserInfo->Add(iRejRunStr);
+
+  snprintf(nstr, 2000, "RejectedLHC=%i", iRejLHC);
+  TObjString *iRejLHCStr = new TObjString(nstr);
+  aUserInfo->Add(iRejLHCStr);
+
+  snprintf(nstr, 2000, "RejectedDet=%i", iRejDet);
+  TObjString *iRejDetStr = new TObjString(nstr);
+  aUserInfo->Add(iRejDetStr);
+
+  snprintf(nstr, 2000, "RejectedEvt=%i", iRejEvt);
+  TObjString *iRejEvtStr = new TObjString(nstr);
+  aUserInfo->Add(iRejEvtStr);
+
+  return chain;
 }