Ignore:
Timestamp:
08/20/04 11:25:36 (20 years ago)
Author:
tbretz
Message:
*** empty log message ***
Location:
trunk/MagicSoft/Mars/mfileio
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/MagicSoft/Mars/mfileio/MRead.h

    r4601 r4694  
    1717    MRead() : fSelector(NULL) {}
    1818
    19     virtual UInt_t GetEntries() = 0;
    20     virtual Bool_t Rewind();
     19    virtual UInt_t  GetEntries() = 0;
     20    virtual TString GetFileName() const = 0;
     21    virtual Bool_t  Rewind();
    2122
    2223    void SetSelector(MFilter *f) { fSelector = f; }
  • trunk/MagicSoft/Mars/mfileio/MReadMarsFile.cc

    r3682 r4694  
    191191    if (!tlist)
    192192    {
    193         *fLog << err << dbginf << "ERROR - Task List not found in Parameter List." << endl;
     193        *fLog << err << dbginf << "ERROR - MTaskList not found in Parameter List." << endl;
    194194        return kFALSE;
    195195    }
  • trunk/MagicSoft/Mars/mfileio/MWriteAsciiFile.cc

    r3336 r4694  
    188188// a warning message is print.
    189189//
    190 Bool_t MWriteAsciiFile::CheckAndWrite() const
     190Bool_t MWriteAsciiFile::CheckAndWrite()
    191191{
    192192    Bool_t written = kFALSE;
  • trunk/MagicSoft/Mars/mfileio/MWriteAsciiFile.h

    r3336 r4694  
    2121    TObjArray fAutoDel; //! List of object to be deleted in the destructor
    2222
    23     virtual Bool_t CheckAndWrite() const;
     23    virtual Bool_t CheckAndWrite();
    2424    virtual Bool_t IsFileOpen() const;
    2525    virtual Bool_t GetContainer(MParList *pList);
  • trunk/MagicSoft/Mars/mfileio/MWriteFile.h

    r3336 r4694  
    88class MWriteFile : public MTask
    99{
     10protected:
     11    Bool_t ReInit(MParList *pList);
     12
    1013private:
    1114    Int_t PreProcess(MParList *pList);
    1215    Int_t Process();
    1316    Int_t PostProcess();
    14     Bool_t ReInit(MParList *pList);
    1517
    1618    virtual Bool_t      IsFileOpen() const = 0;
    17     virtual Bool_t      CheckAndWrite() const = 0;
     19    virtual Bool_t      CheckAndWrite() = 0;
    1820    virtual Bool_t      GetContainer(MParList *pList) = 0;
    1921    virtual const char *GetFileName() const = 0;
  • trunk/MagicSoft/Mars/mfileio/MWriteRootFile.cc

    r3710 r4694  
    1818!   Author(s): Thomas Bretz, 6/2001 <mailto:tbretz@astro.uni-wuerzburg.de>
    1919!
    20 !   Copyright: MAGIC Software Development, 2000-2003
     20!   Copyright: MAGIC Software Development, 2000-2004
    2121!
    2222!
     
    2424
    2525/////////////////////////////////////////////////////////////////////////////
    26 //                                                                         //
    27 // MWriteRootFile                                                          //
    28 //                                                                         //
    29 // This is a writer to store several containers to a root file.            //
    30 // The containers are added with AddContainer.                             //
    31 // To understand how it works, see base class MWriteFile                   //
    32 //                                                                         //
    33 // Warning: Checkout the Warning in MTaskList.                             //
    34 //                                                                         //
     26//
     27// MWriteRootFile
     28//
     29// This is a writer to store several containers to a root file.
     30// The containers are added with AddContainer.
     31// To understand how it works, see base class MWriteFile
     32//
     33// Warning: Look at the Warning in MTaskList.
     34//
     35// There is a special mode of operation which opens a new file for each new
     36// file read by the reading task (opening the new file is initiated by
     37// ReInit()) For more details se the corresponding constructor.
     38//
    3539/////////////////////////////////////////////////////////////////////////////
    3640#include "MWriteRootFile.h"
     
    4044#include <TFile.h>
    4145#include <TTree.h>
     46#include <TRegexp.h>
    4247
    4348#include "MLog.h"
    4449#include "MLogManip.h"
    4550
     51#include "MRead.h"
    4652#include "MParList.h"
    4753
     
    5157using namespace std;
    5258
    53 static const TString gsDefName  = "MWriteRootFile";
    54 static const TString gsDefTitle = "Task which writes a root-output file";
     59const TString MWriteRootFile::gsDefName  = "MWriteRootFile";
     60const TString MWriteRootFile::gsDefTitle = "Task which writes a root-output file";
     61
     62void MWriteRootFile::Init(const char *name, const char *title)
     63{
     64    fName  = name  ? name  : gsDefName.Data();
     65    fTitle = title ? title : gsDefTitle.Data();
     66
     67    //
     68    // Set the Arrays the owner of its entries. This means, that the
     69    // destructor of the arrays will delete all its entries.
     70    //
     71    fBranches.SetOwner();
     72
     73    //
     74    // Believing the root user guide, TTree instanced are owned by the
     75    // directory (file) in which they are. This means we don't have to
     76    // care about their destruction.
     77    //
     78    //fTrees.SetOwner();
     79}
    5580
    5681// --------------------------------------------------------------------------
     
    6186MWriteRootFile::MWriteRootFile() : fOut(NULL)
    6287{
    63     fName  = gsDefName;
    64     fTitle = gsDefTitle;
    65 
     88    Init();
     89
     90    //
     91    // Set the Arrays the owner of its entries. This means, that the
     92    // destructor of the arrays will delete all its entries.
     93    //
    6694    fBranches.SetOwner();
     95}
     96
     97// --------------------------------------------------------------------------
     98//
     99// Use this constructor to run in a special mode.
     100//
     101// In this mode for each input file a new output file is written. This
     102// happens in ReInit.
     103//
     104// comp:        Compression Level (see TFile, TBranch)
     105// rule:        Rule to create output file name (see GetNewFileName())
     106// overwrite:   Allow newly created file to overwrite old files ("RECREATE")
     107// ftitle:      File title stored in the file (see TFile)
     108// name, title: Name and title of this object
     109//
     110MWriteRootFile::MWriteRootFile(const Int_t comp,
     111                               const char *rule,
     112                               const Bool_t overwrite,
     113                               const char *ftitle,
     114                               const char *name,
     115                               const char *title) : fSplitRule(rule)
     116{
     117    Init(name, title);
     118
     119    //
     120    // Open a TFile in dummy mode! This is necessary to be able to create
     121    // the trees and branches, which are then (in ReInit) moved to
     122    // a valid file. (Stupid workaround - but does a good job)
     123    //
     124    fOut = new TFile("/dev/null", overwrite?"RECREATE":"NEW", ftitle, comp);
    67125}
    68126
     
    81139                               const char *title)
    82140{
    83     fName  = name  ? name  : gsDefName.Data();
    84     fTitle = title ? title : gsDefTitle.Data();
    85 
    86     //
    87     // Set the Arrays the owner of its entries. This means, that the
    88     // destructor of the arrays will delete all its entries.
    89     //
    90     fBranches.SetOwner();
    91 
    92     //
    93     // Believing the root user guide, TTree instanced are owned by the
    94     // directory (file) in which they are. This means we don't have to
    95     // care about their destruction.
    96     //
    97     //fTrees.SetOwner();
     141    Init(name, title);
     142
     143    //
     144    // If no name is given we open the TFile in some kind of dummy mode...
     145    //
     146    if (!fname)
     147    {
     148        fOut = new TFile("/dev/null", "READ", ftitle, comp);
     149        return;
     150    }
    98151
    99152    TString str(fname);
     
    112165// properly.
    113166//
    114 MWriteRootFile::~MWriteRootFile()
     167void MWriteRootFile::Close()
    115168{
    116169    //
     
    130183    //
    131184    delete fOut;
     185    fOut = 0;
    132186
    133187    //
     
    139193
    140194    *fLog << inf << "Output File closed and object deleted." << endl;
     195}
     196
     197// --------------------------------------------------------------------------
     198//
     199// call Close()
     200//
     201MWriteRootFile::~MWriteRootFile()
     202{
     203    Close();
    141204}
    142205
     
    350413            *fLog << inf << "Branch '" << cname << "' already existing... updating." << endl;
    351414            branch->SetAddress(entry->GetAddress());
     415
     416            if (!fSplitRule.IsNull())
     417            {
     418                *fLog << warn << endl;
     419                *fLog << "WARNING:   You are updating an existing branch.  For this" << endl;
     420                *fLog << "     case file-splitting mode is not allowed... disabled!" << endl;
     421                *fLog << endl;
     422                fSplitRule = "";
     423            }
    352424        }
    353425        else
     
    365437
    366438            branch = tree->Branch(branchname, cont->ClassName(), entry->GetAddress());
     439
    367440            //
    368441            // If the branch couldn't be created we have a problem.
     
    376449
    377450            *fLog << "done." << endl;
     451
     452            if (!tree->TestBit(kIsNewTree) && !fSplitRule.IsNull())
     453            {
     454                *fLog << warn << endl;
     455                *fLog << "WARNING:   You  have  created  a new branch  in  an existing tree." << endl;
     456                *fLog << "     For this case file-splitting mode is not allowed... disabled!" << endl;
     457                *fLog << endl;
     458                fSplitRule= "";
     459            }
    378460        }
    379461
     
    384466        entry->SetBranch(branch);
    385467    }
     468
    386469    return kTRUE;
    387470}
     
    401484// has the write flag, all containers in this tree are filled!
    402485//
    403 Bool_t MWriteRootFile::CheckAndWrite() const
     486Bool_t MWriteRootFile::CheckAndWrite()
    404487{
    405488    TObject *obj;
     
    438521    // Loop over all tree entries
    439522    //
    440     TIter NextTree(&fTrees);
    441     while ((obj=NextTree()))
    442     {
    443         TTree *t = (TTree*)obj;
     523    const Int_t n = fTrees.GetEntriesFast();
     524
     525    for (int idx=0; idx<n; idx++)
     526    {
     527        TTree *t = (TTree*)fTrees[idx];
    444528
    445529        //
     
    455539        //
    456540        t->ResetBit(kFillTree);
     541
    457542        if (!t->Fill())
    458543        {
     
    461546        }
    462547    }
     548
     549    //
     550    // For more information see TTree:ChangeFile()
     551    //
     552    TTree *t0 = (TTree*)fTrees[0];
     553    if (!t0 || fOut==t0->GetCurrentFile())
     554        return kTRUE;
     555
     556    *fLog << warn << endl;
     557    *fLog << "WARNING - MWriteRootFile:   Root's  TTree/TFile   has  opened   a  new  file" << endl;
     558    *fLog << "  automatically.  You can change this behaviour using TTree::SetMaxTreeSize." << endl;
     559    *fLog << "  You won't be able to read splitted  files  correctly with MReadMarsFile if" << endl;
     560    *fLog << "  they have more than one entry in 'RunHeaders' or you try to read more than" << endl;
     561    *fLog << "  one of such sequences at once." << endl;
     562    *fLog << endl;
     563
    463564    return kTRUE;
    464565}
     
    466567// --------------------------------------------------------------------------
    467568//
     569// Open a new file with the ame fname. Move all trees and branches from the
     570// old file to the new file.
     571//
     572Bool_t MWriteRootFile::ChangeFile(const char *fname)
     573{
     574    //
     575    // The following code is more or less a copy of TTree::ChangeFile
     576    //
     577    const Int_t   compr = fOut->GetCompressionLevel();
     578    const TString title = fOut->GetTitle();
     579
     580    *fLog << inf << "MWriteRootFile - Open new file " << fname << " (Title=" << title << ", Compression=" << compr << ")" << endl;
     581
     582    // Open new file with old setup
     583    TFile *newfile = TFile::Open(fname, "RECREATE", title, compr);
     584    if (!newfile)
     585    {
     586        *fLog << err << "ERROR - Cannot open new file " << fname << endl;
     587        return kFALSE;
     588    }
     589
     590    // Print statistics of old file
     591    const TString n = GetFileName();
     592    if (!n.IsNull() && n!=TString("/dev/null"))
     593        Print();
     594
     595    if (fOut->IsOpen())
     596        fOut->Write();
     597
     598    // Move all trees from the old file to the new file
     599    TObject *obj=0;
     600    while ((obj = fOut->GetList()->First()))
     601    {
     602        // Remove obj from old file (otherwise deleting
     603        // the old file will delete the objs)
     604        fOut->GetList()->Remove(obj);
     605
     606        // If this is not a tree do nothing.
     607        if (!obj->InheritsFrom("TTree"))
     608            continue;
     609
     610        // process all trees in the old file
     611        TTree *t = (TTree*)obj;
     612
     613        // reset and move to new file (this is done implicitly for all branches)
     614        t->Reset();
     615        t->SetDirectory(newfile);
     616    }
     617
     618    // Close/delete the old file (keys already written above)
     619    delete fOut;
     620
     621    // Replace current with new file
     622    fOut = newfile;
     623
     624    // Change current directory to new file
     625    gFile = fOut;
     626
     627    return kTRUE;
     628}
     629
     630// --------------------------------------------------------------------------
     631//
     632// A rule looks like:
     633//   "outputpath{s/source/destination}"
     634//
     635// outpath:                the output path into which the files are written
     636// {s/source/destination}  a substitution rule for the filename
     637//   while source can be a regular expression everything which matches this
     638//   regular expression (see TRegexp) will be replaced by destination.
     639//   Warning: The algorithm is recursive you may create endless loops!
     640//
     641// Example:
     642//   inputfile: /data/MAGIC/Period016/rootdata/20040621_23210_D_Mkn421_E.root
     643//   rule:      /outpath/{s/_D_/_Y_}
     644//   outfile:   /outpath/20040621_23210_Y_Mkn421_E.root
     645//
     646// If you need more difficult rules please send me an eMail...
     647//
     648TString MWriteRootFile::GetNewFileName(const char *inname) const
     649{
     650    // Remove the path from the filename
     651    TString fname(inname);
     652    if (fname.Last('/')>=0)
     653        fname.Remove(0, fname.Last('/')+1);
     654
     655    // Make a copy of the rule
     656    TString rule(fSplitRule);
     657
     658    // [characte class], ^ do not, [^{}] do not match { and }, [^{}]+ match at least not one { or }
     659    const TRegexp subst0("{s/[^{}/]+/[^{}/]+}");
     660
     661    TString path;
     662    Bool_t first = kTRUE;
     663
     664    Ssiz_t idx=0;
     665    while (1)
     666    {
     667        // Find a substitution exprsssion
     668        Ssiz_t len = 0;
     669        idx = subst0.Index(rule, &len);
     670        if (idx<0)
     671            break;
     672
     673        // If the first substitution expression is found in the rule
     674        // determin the path from everything before
     675        if (first)
     676        {
     677            path=rule(0, idx);
     678            first = kFALSE;
     679        }
     680
     681        // Extract a substitution expression
     682        TString expr = rule(idx, len);
     683        rule.Remove(idx, len);
     684
     685        expr.Remove(0,3);
     686        expr.Remove(expr.Length()-1);
     687
     688        // In all cases this is well defined (see Regexp)
     689        const Ssiz_t pos = expr.First('/');
     690
     691        // Split substitution rule into source and destination
     692        const TString src  = expr(0, pos);
     693        const TString dest = expr(pos+1, expr.Length());
     694
     695        // Replace source by destination
     696        const TRegexp regexp(src);
     697        while (1)
     698        {
     699            TString sub = fname(idx+dest.Length());
     700            idx = regexp.Index(fname, &len);
     701            if (idx<0)
     702                break;
     703
     704            fname.Replace(idx, len, dest);
     705        }
     706    }
     707
     708    // Check if we have a trailing '/'
     709    if (!path.IsNull() && path[path.Length()-1]!='/')
     710        path.Append("/");
     711
     712    // Create full qualified pathname
     713    path += fname;
     714    return path;
     715}
     716
     717// --------------------------------------------------------------------------
     718//
     719// ReInit. If file splitting is not allowed call MWriteFile::ReInit.
     720//
     721// In other cases get MRead from the TaskList (splitting is switched of if
     722// this is impossible).
     723//
     724// Convert the input- into a new output file-name.
     725//
     726// Open a new file, change all trees to the new file (calling ChangeFile()),
     727// and close the old one.
     728//
     729// Call MWriteFile::ReInit()
     730//
     731Bool_t MWriteRootFile::ReInit(MParList *pList)
     732{
     733    if (fSplitRule.IsNull())
     734        return MWriteFile::ReInit(pList);
     735
     736    MRead *read = (MRead*)pList->FindTask("MRead");
     737    if (!read)
     738    {
     739        *fLog << warn;
     740        *fLog << "WARNING: No Task 'MRead' found in the tasklist.  This task is" << endl;
     741        *fLog << "  necessary  to  get  the filename.  Without  a filename file" << endl;
     742        *fLog << "  file splitting is not allowed... disabled!" << endl;
     743        *fLog << endl;
     744        fSplitRule = "";
     745        return kTRUE;
     746    }
     747
     748    const TString fname = GetNewFileName(read->GetFileName());
     749    if (!ChangeFile(fname))
     750        return kFALSE;
     751
     752    return MWriteFile::ReInit(pList);
     753}
     754
     755// --------------------------------------------------------------------------
     756//
    468757// return open state of the root file.
    469758//
    470759Bool_t MWriteRootFile::IsFileOpen() const
    471760{
    472     return fOut->IsOpen();
     761    const char *n = fOut->GetName();
     762    return n==0 || *n==0 ? kTRUE : fOut->IsOpen();
    473763}
    474764
     
    479769const char *MWriteRootFile::GetFileName() const
    480770{
    481     return fOut->GetName();
     771    const char *n = fOut->GetName();
     772    return n==0 || *n==0 ? "<dummy>" : n;
    482773}
    483774
  • trunk/MagicSoft/Mars/mfileio/MWriteRootFile.h

    r3336 r4694  
    77#ifndef ROOT_TObjArray
    88#include <TObjArray.h>
     9#endif
     10#ifndef ROOT_TArrayL
     11#include <TArrayL.h>
    912#endif
    1013
     
    6871{
    6972private:
    70     TFile *fOut;
     73    static const TString gsDefName;
     74    static const TString gsDefTitle;
    7175
    72     TObjArray fBranches;
    73     TObjArray fTrees;     //!
     76    TFile *fOut;             // Current file
    7477
    75     //UInt_t fNumEvents; //! Number of events written in a run
     78    TObjArray fBranches;     // List of Branch setup (MRootFileBranch)
     79    TObjArray fTrees;        //! List of trees
    7680
    77     Bool_t      CheckAndWrite() const;
    78     Bool_t      IsFileOpen() const;
    79     Bool_t      GetContainer(MParList *pList);
    80     const char *GetFileName() const;
    81 
    82     void StreamPrimitive(ofstream &out) const;
    83     //Bool_t ReInit(MParList *pList);
     81    TString fSplitRule;      // file splitting allowed if rule existing (done in ReInit)
    8482
    8583    enum {
    8684        kFillTree  = BIT(14),
     85        // Be carefull these bits are already in use!
    8786        // TBranch::kAutoDelete = BIT(15)
    8887        // TBranchElement::kDeleteObject = BIT(16)
     
    9089    };
    9190
     91    // File handling
     92    void    Close();
     93    TString GetNewFileName(const char *fname) const;
     94    Bool_t  ChangeFile(const char *fname);
     95
     96    // MWrite
     97    Bool_t      CheckAndWrite();
     98    Bool_t      IsFileOpen() const;
     99    Bool_t      GetContainer(MParList *pList);
     100    const char *GetFileName() const;
     101
     102    // MTask
     103    Bool_t ReInit(MParList *pList);
     104    void   StreamPrimitive(ofstream &out) const;
     105
     106    // Constructor
     107    void Init(const char *name=0, const char *title=0);
     108
    92109public:
    93110    MWriteRootFile();
     111    MWriteRootFile(const Int_t comp,
     112                   const char *rule,
     113                   const Bool_t overwrite=kTRUE,
     114                   const char *ftitle="Untitled",
     115                   const char *name=NULL,
     116                   const char *title=NULL);
    94117    MWriteRootFile(const char *fname,
    95118                   const Option_t *opt="RECREATE",
    96119                   const char *ftitle="Untitled",
    97                    const Int_t comp=9,
     120                   const Int_t comp=2,
    98121                   const char *name=NULL,
    99122                   const char *title=NULL);
    100123    ~MWriteRootFile();
    101124
    102 
    103125    void AddContainer(const char *cname,   const char *tname=NULL, Bool_t must=kTRUE);
    104126    void AddContainer(MParContainer *cont, const char *tname=NULL, Bool_t must=kTRUE);
    105 
    106127
    107128    void Print(Option_t *t=NULL) const;
Note: See TracChangeset for help on using the changeset viewer.