RUNDB classes revisted (was Re: New DB additions to BRAT)

From: Christian Holm Christensen (cholm@hehi03.nbi.dk)
Date: Tue Jan 16 2001 - 13:52:14 EST

  • Next message: Pawel Staszel: "BRAT updates of DC tracking"

    Hi Kris et al, 
    
    I've revisited the classes in BRAT that corresponds to the run
    database RUNDB. I haven't commited these changes yet, but I will,
    assuming no one has anything to object. Baring in mind that many of
    the collaborators are currently tied up in QM2001, I'll give you until
    early next week to respond. 
    
    However, I'll first like to comment on the changes Kris recently
    made. 
    
    On Fri, 12 Jan 2001 18:33:38 -0600
    hagel@comp.tamu.edu wrote
    concerning ": New DB additions to BRAT":
    > Hello everyone,
    > This is to let you know that I have added two new DB classes to BRAT.
    > They are the first iterations of BrPass and BrPassDb.  Other files in
    > the DB directory were modified to enable implementation of these
    > classes.
    
    I've tried to be consistent in the naming scheme of the classes for
    the databases. That is, they should have the form 
    
        BrDb<Table> 
    
    where table is the corresponding table in a database. Could you
    please conform to this convention, as it makes it so much easier to
    figure out what the classes are for, where they get thier data, etc. 
    
    Also, I've tried to maintain a complete one-to-one correspondence
    between the BrDb<Table> classes and the tables in the databases. That
    is, BrDb<Table> will have one and only one member corresponding to one
    and only one column in the database table. The  BrDb<Table> classes
    should not have any additional members (other then array size
    parameters) compared to the columns in the database table. 
    
    Let me illustrate via an example. Suppose you have table Foo in some
    database, with the columns 
    
      Table Foo 
      ---------------
        id     INT
        bar    FLOAT 
        baz    TEXT 
    
    Then the corresponding BRAT class BrDbFoo will be 
    
       class BrDbFoo : public BrDbTable {
       private:
    	    // Int_t fBDID is in the base class BrDbTable. 
    	    Float_t fBar;     // Bar column
    	    Int_t   fBazSize; // Number of elements in fBaz
    	    Char_t* fBaz;     //[fBazSize] Baz column
    	  public:
    	    BrDbFoo(Float_t       bar, 
    	            const Char_t* baz) {
    	      fBar     = bar;
    	      fBazSize = strlen(baz) + 1; 
    	      fBaz     = new Char_t[fBazSize];
    	      strcpy(fBaz, baz);
    	      fBaz[fBazSize-1] = '\0';
         }
         static BrDbFoo* SingleInstance(TSQLRow* row) {
           BrDbFoo* foo = 
    	        new BrDbFoo(strtod(row->GetField(1),NULL),
    		            row->GetField(2));
           foo->SetDBID(strtol(row->GetField(0),NULL,0));
           return foo;
         }
         // And so on ...
         ClassDef(BrDbFoo, 1) // Database class for table Foo
      };
    
    The class should contain no more and no less. Even if some other
    table, say Gnus, referenced table Foo, there should be no pointer
    reference or the like in the BRAT classes. The interrelation ship
    between tables is handled by managers in BRAT, not the dataobjects
    themselves. 
    
    Hence, following this line, Br(Db)Pass SHOULD NOT contain the two
    arrays 
    
      TObjArray *fInputFileList;
      TObjArray *fOutputFileList;
    
    This line of reasoning also implies, that the Br<database>Db classes
    should not try to be too clever, and it's not the design philosophy of
    these classes to be the managers for the inter-relationsships - that
    is what a class like BrElementParameterManager does. The
    Br<database>Db classes are mearly interfaces, or drivers, to the
    underlying database manager.
    
    Hence, the BrPassDb should not have only a method to retive Br(Db)Pass
    objects, but also for retreving BrPassInputFile and BrPassOutputFile
    objects, much like BrCalibrationsDb can retrive objects of classes
    BrDbParameter, BrDbRevision, BrDbRevisionType, etc. 
    
    Incidently, your code will look much better if you stick to that
    design. And it will be much easier to implement drivers for other
    database managers like - oh say - ROOT!
    
    Another class, say BrPassManager, should manage the object and request
    the proper rows from the database manager, using the Br<database>Db
    classes. 
    
    > As noted, this is the first iteration of these classes.  BrPass is meant
    > to be a class used with appropriate managers when doing the various
    > reduction passes.  So far it keeps track of the start time, the end time
    > and run number as well as the input and output files of the various
    > passes.  
    
    Why do we want to store information like that in the database? Is it
    intended to be used by every bloody application chunking through
    BRAHMS data, or only some subset? 
    
    > These are to be put in the BRAHMS MySQL db and are obviously
    > constructed under the DB framework Christian wrote.  BrPassDb interacts
    > with BrMainDb and does the work of getting things in and out of the DB.
    > There is also a program in dbapp called CreatePass which creates the
    > tables used for the package.
    
    In the code CreatePass.cxx you write 
    
         //What is this for???
        cout << "Adding sequence table" << endl;
        passDb->CreateSequence();
    
    This is to set up a sequence (a table with only one row, an integer)
    on that database. Every row in every table should be uniquely defined
    in some way. Rather then relying on MySQL's non-ANSI AUTOINCREMENT
    feature, I implemted unigue ids over the database, using a
    sequnce. This makes sure that any piece of data can uniquely be
    identified in the database. 
    
    End of comments ------------------------------------------------------
    
    As to the revision of the RUNDB classes. 
    
    These classes were originally made by Kris, and suffer from the same
    non-conformance (sorry Kris, but it's true) as I've mentioned above. 
    
    Here's what I've done: 
    
    Created a one-to-one mapping from KO's tables to BRAT classes: 
    
    	Runs                    <->     BrDbRun            (*)
            Files                   <->     BrDbFile           (*)
    	ConditionsBrahmsMagnets <->     BrDbMagnet         (**)
    	ConditionsVars          <->     BrDbConditionsVar  (*)
    	ConditionsData          <->     BrDbConditionsData     (***)
    	ShiftReports            <->     BrDbShiftReport    (*) (***)
    
    (*)   I've dropped the plural "s" since objects of these classes really
          corresponds to a single entry in those tables. I guess KO felt
          that a table is a collection of similar things - hence the "s". I
          see tables as a _type_ (or class if you will) as I've argued in
          the second Database design document 
          (see http://www.rhic.bnl.gov/~cholm/db/bratdb-v1/node10.html) -
          hence no "s"
    (**)  "BrDbConditionsBrahmsMagnets" is just to blody long, and the
          "Brahms" is completly redundant. So far, I'm not sure wether this
          table is actually used (there's data in it alright) since the
          same information is also in the Runs table. KO can probably
          comment more on this
    (***) These to tables are not used at the moment. They are in fact
          pretty similar the Parameter/Revision tables in BrahmsCalib. 
    
    Notice that BrDbRun, BrDbFile, etc. has all the information that is in
    a given row of the RUNDB tables - i.e., the scalars are now avaliable
    via BrDbRun objects and so on. 
    
    One can use BrDbShiftReport to pretty print the shift reports :-) (it
    has a very simple Print() method) from within the user application. 
    
    None of these classes will allow them selves to be commited to the
    database. That is the job of the DAQ! Of course, should KO decide to
    use ROOT/BRAT for the DAQ, then these classes could be changed. 
     
    Changed BrRunsDb to use these classes. This means, that if you used to
    do 
    
       BrRunsDb   runDb = mainDb->ConnectToRun("query", "query-only"); 
       BrRun*     run   = runDb->GetRun("runno = 2535");
       BrRunFile* file  = run->GetFileSeq(0);
    
    you'll now do 
    
       BrRunsDb   runDb = mainDb->ConnectToRun("query", "query-only"); 
       BrDbRun*   run   = runDb->GetRun(2535);
       BrDbFile*  file  = runDb->GetFile(2535,0);
    
    You can also get a full list of sequnces for a given run by 
    
        TObjArray* files = runDb->GetXFile(2535);
        TIter nextSeq(files);
        BrDbFile*  file  = 0;
        while((file = (BrDbFile*)nextSeq())) {
          // below is probably not correct, but meant as illustration
          rawDataInput->Open(file->GetSpoolFile(), "READ");
          if (!rawDataInput)  // Panic!!!!
            continue;
          ...
          while(...) // Event loop 
        }
    
    This should really be manged by some manager, that will serve file
    names to the BrIOModule, serve magnet settings to track matchers and
    so on. I'm not quite sure how to do that yet, so any suggestions would
    be more then welcome. 
    
    As I've said, these changes are not commited to BRAT yet, but I do
    belive they are for the better. 
    
    ----------------------------------------------------------------------
    
    Some thought of the geometry database. 
    
    I thought it be nice, if we could use the geometry database for GEANT
    input as well as for data analysis. 
    
    That would mean, that you'd store the full GEANT geometry in the
    database, and for analysis only use a subset. Ofcourse, this demands
    that we can get GEANT to talk to a MySQL database (probably via C). 
    
    We'd then have tables like 
    
         Material:
         ---------
         Id
         Name
         A, Z, Density
         ...
    
         Medium:
         -------
         Id
         MaterialId
         FieldType
         ...
    
         Shape:
         ------
         Id
         Name 
         Shape (like BRIK, CONS, ...)
         ....
    
         Position:
         ---------
         ShapeId
         RotationId
         X, Y, Z
         ...
    
         Rotation:
         ---------
         Id
         Theta1, theta2, theta3
         phi1, phi2, phi3
    
    Incidently, this will make it much easier to visuallise data in ROOT. 
    Also, it'fd be relatively trivial to maintain direct correspondence of
    simulation and reality (maybe even Nature?!?). 
    
    I believe STAR has done something like that, but I'm not sure. Perhaps
    some at QM2001 could grab Valerio Fine and ask him?      
    
    
    
    Phew that got to longer then I expected - sorry. 
    
    Yours,
    
    Christian  -----------------------------------------------------------
    Holm Christensen                             Phone:  (+45) 35 35 96 91 
      Sankt Hansgade 23, 1. th.                  Office: (+45) 353  25 305 
      DK-2200 Copenhagen N                       Web:    www.nbi.dk/~cholm    
      Denmark                                    Email:       cholm@nbi.dk
    



    This archive was generated by hypermail 2b29 : Tue Jan 16 2001 - 13:53:26 EST