BRAT 2.4.5
Class index
Full class index
brahmlib
BRAHMS
ROOT page
// BrCalibrationsDB
//
// Database engine wrapper for calibration data. This is a singleton
// object. After construction, one can get a pointer to the connection
// via static message BrRootCalibrationsDb::Instance(). 
//

//
// $Id: BrRootCalibrationsDb.cxx,v 1.1 2001/10/08 10:41:28 cholm Exp $
// $Author: cholm $
// $Date: 2001/10/08 10:41:28 $
// $Copyright: 2000 Brahms Collaboration
//

#include "BrRootCalibrationsDb.h"
#ifndef BRAT_BrException
#include "BrException.h"
#endif
#ifndef WIN32 
#include <cstdlib>
#include <iostream>
#else 
#include <stdlib.h>
#include <iostream.h>
#endif

//____________________________________________________________________
ClassImp(BrRootCalibrationsDb);

//____________________________________________________________________
 BrRootCalibrationsDb::BrRootCalibrationsDb(const Char_t* name, 
					   const Char_t* title)
{
  // Normal constructor. Singleton.  
  fImplementation = new BrRootDb(name, title);
  fRevision       = 0;
  fRevisionType   = 0;  
  fParameter      = 0;
}

//____________________________________________________________________
 Bool_t BrRootCalibrationsDb::Connect(Option_t* option) 
{
  // Overloaded here, so that we can get pointers to the tables. 
  if (!fImplementation->Connect()) 
    return kFALSE;

  TFile* connection = (TFile*)fImplementation->GetConnection();
  if (!connection) 
    return kFALSE; 

  Bool_t retval = kTRUE;
  if (!(fParameter =
	(TObjArray*)connection->Get(BrDbParameter::kTableName))) 
    retval = kFALSE;
  if (!(fRevision =
	(TObjArray*)connection->Get(BrDbRevision::kTableName))) 
    retval = kFALSE;
  if (!(fRevisionType =
	(TObjArray*)connection->Get(BrDbRevisionType::kTableName))) 
    retval = kFALSE;

  if (!retval) {
    Close();
    delete fImplementation;
    fImplementation = 0;
  }
  return retval;
}

//____________________________________________________________________
 BrCalibrationsDb* BrRootCalibrationsDb::Instance(void) 
{
  // Returns an instance of the Calibration Database connection. 
  // Connection _must_ be constructed somewhere previous to calling
  // this static method. 
  if (!fgInstance) 
    fgInstance = new BrRootCalibrationsDb("","");
  
  return fgInstance;
}

//____________________________________________________________________
 void BrRootCalibrationsDb::AddRevision(BrDbRevision* revision)
{
  // Add a Revision to the database. Warns if there exist overlapping
  // revsisions wiith the same type. 
  if (!IsConnected())
    return;

  if (revision->GetParameterID() <= 0) 
    throw new BrError("BrRootCalibrationsDb::AddRevision",
		      "Parameter ID '%d' not valid, giving up", 
		      revision->GetParameterID());
  
  if (revision->GetTypeID() < -1) 
    throw new BrError("BrRootCalibrationsDb::AddRevision",
		      "Revision Type ID unknown, giving up");

  if (!revision->GetArray() || revision->GetEntries() < 1) 
    throw new BrError("BrRootCalibrationsDb::AddRevision",
		      "Can not add empty revision");

  if (strlen(revision->GetComment()) < 16)
    cerr << "BrRootCalibrationsDb::AddRevision: "
      "Comment string lesss then 16 characters - investigate!" 
	 << endl;

  TIter next(fRevision);
  BrDbRevision* r = 0;
  Int_t overlap = 0;
  while((r = (BrDbRevision*)next())) {
    
    if (r->GetParameterID() == revision->GetParameterID() &&
	r->GetValidStart() == revision->GetValidStart() &&
	r->GetValidEnd() == revision->GetValidEnd())

      if (r->GetTypeID() == revision->GetTypeID())
	overlap++;
  }
  if (overlap > 0) 
    cerr << "BrRootCalibrationsDb::AddRevision: " 
	 << "There exists overlapping Revisions in the data base " 
	 << "with the same type ID (" << revision->GetTypeID() 
	 << ") as the one to be added. Real danger of database "
	 << "corruption. Investigate!" << endl;

  LockTables(BrDbRevision::kTableName);
  revision->SetDBID(Increment());
  fRevision->Add(revision);
  fRevision->Write(BrDbRevision::kTableName, 
		   TObject::kOverwrite|TObject::kSingleKey);
  UnLockTables();
}

//____________________________________________________________________
 void BrRootCalibrationsDb::AddRevisionType(BrDbRevisionType* type) 
{
  // Add a Revision Type to the database. Fails if it allready exists
  // in the database (throws a BrExcpetion)
  if (!IsConnected())
    return;

  if (strlen(type->GetName()) < 1) 
    throw new BrWarning("BrRootCalibrationsDb::AddRevisionType",
			"Revision Type MUST have a name");
  if (strlen(type->GetComment()) < 16) 
    throw new BrWarning("BrRootCalibrationsDb::AddRevisionType",
			"Revision Type MUST have a comment");

  if (fRevisionType->FindObject(type->GetName()))
    throw new BrWarning("BrRootCalibrationsDb::AddRevisionType",
			"Revision Type %s already exist", 
			type->GetName());

  LockTables(BrDbRevisionType::kTableName);
  type->SetDBID(Increment());
  fRevisionType->Add(type);
  fRevisionType->Write(BrDbRevisionType::kTableName, 
		       TObject::kOverwrite|TObject::kSingleKey);
  UnLockTables();
}

//____________________________________________________________________
 void BrRootCalibrationsDb::AddParameter(BrDbParameter* param) 
{
  // Add a parameter to the database. Fails if it allready exists in
  // the database (throws a BrExcpetion)
  if (!IsConnected())
    return;

  if (strlen(param->GetName()) < 1) 
    throw new BrWarning("BrRootCalibrationsDb::AddParameter",
			"Parameter MUST have a name");
  if (param->GetReferenceID() < 1) 
    throw new BrWarning("BrRootCalibrationsDb::AddParameter",
			"Parameter MUST refer to something");
  if (strlen(param->GetTypeName()) < 1) 
    throw new BrWarning("BrRootCalibrationsDb::AddParameter",
			"Parameter MUST have a type");

  TString n(param->GetName());
  TIter next(fParameter);
  BrDbParameter* p = 0;
  while ((p = (BrDbParameter*)next())) {
    if (n == p->GetName() && 
	p->GetReferenceID() == param->GetReferenceID()) 
      throw new BrWarning("BrRootCalibrationsDb::AddParameter",
			  "Parameter %s already exist", 
			  param->GetName());
  }
  LockTables(BrDbParameter::kTableName);
  param->SetDBID(Increment());
  fParameter->Add(param);
  fParameter->Write(BrDbParameter::kTableName, 
		    TObject::kOverwrite|TObject::kSingleKey);
  UnLockTables();
}

//____________________________________________________________________
 TObjArray* BrRootCalibrationsDb::GetXParameter(const Char_t* condition) 
{
  // Returns (unconditionally) all parameters
  if (!IsConnected())
    return 0;
  return fParameter; 
} 

//____________________________________________________________________
 TObjArray* BrRootCalibrationsDb::GetXRevision(const Char_t* condition) 
{
  // Returns (unconditionally) all Revisions
  if (!IsConnected())
    return 0;
  return fRevision; 
}

//____________________________________________________________________
 TObjArray* BrRootCalibrationsDb::GetXRevisionType(const Char_t* condition) 
{
  // Returns (unconditionally) all RevisionTypes
  if (!IsConnected())
    return 0;
  return fRevisionType; 
}
	
//____________________________________________________________________
 BrDbParameter* BrRootCalibrationsDb::GetParameter(const Char_t* condition) 
{
  // Not implmented.  
  Warning("GetParameter", "not implmented");
  return 0;
}

//____________________________________________________________________
 BrDbParameter* BrRootCalibrationsDb::GetParameter(const Char_t* name,
						  Int_t detectorId) 
{
  // Find a parameter with name <name> belonging to detector
  // <detectorId> 
  if (!IsConnected())
    return 0;
  TString n(name);
  TIter next(fParameter);
  BrDbParameter* p = 0;
  while((p = (BrDbParameter*)next()))
    if (name == p->GetName() && p->GetReferenceID() == detectorId) 
      break;
  return p;
}



//____________________________________________________________________
 BrDbRevision* BrRootCalibrationsDb::GetRevision(const Char_t* condition) 
{
  // Not implmented.  
  Warning("GetRevision", "not implmented");
  return 0;
}

//____________________________________________________________________
 BrDbRevision* BrRootCalibrationsDb::GetRevision(Int_t parameterId, 
						Int_t start,  
						Int_t stop, 
						Int_t typeId, 
						Int_t parameterPolicy) 
{
  // Find a single Revision in the database belonging to Parameter
  // parameterId, inside the time period from start (inclusive) to
  // stop (exclusive), and having type typeId. stop may be negative,
  // in which case the database is serached for time preiod containg
  // start. typeId, may be less then or equal to -1, in which case
  // only standard Revision Types are searched.  If typeId is zero,
  // any revision will be searched. Default is to only search standard
  // revisions. 
  if (!IsConnected())
    return 0;

  TObjArray gotcha;

  TIter next(fRevision);
  BrDbRevision* r = 0;
  while((r = (BrDbRevision*)next())) {
    if (r->GetParameterID() != parameterId) 
      continue;
    if (r->GetValidStart() > start)
      continue;
    Int_t test = (stop < 0 ? start : stop);
    if (r->GetValidEnd() < test) 
      continue;
    test = (typeId <= -1 ? -1 : typeId);
    if (r->GetTypeID() != test) 
      continue;
    
    gotcha.Add(r);
  }

  RevisionSort(gotcha, kFALSE, 0);
  if (gotcha.GetEntries() >= 1) 
    // In case we got one or more Revision back, we return that one
    // the first one, which is the newest because of the above sort
    return (BrDbRevision*)gotcha.At(0);

  if (gotcha.GetEntries() < 1) {
    // If we _didn't_ get _any_ back, then we should follow the policy
    // passed:
    //   0       give up
    //   <0      find a previous valid calibration
    //   >0      find a future valid calibration 
    if (parameterPolicy == 0) 
      throw new BrError("BrRootCalibrationsDb::GetRevision", 
			"No Revisions found in [%d,%d], "
			"giving up because policy is 0",
			start, stop);
    else {
      TIter next(fRevision);
      r = 0;
      while((r = (BrDbRevision*)next())) {
	if (r->GetParameterID() != parameterId) 
	  continue;
	if (parameterPolicy > 0 && r->GetValidStart() <= stop)
	  continue;
	if (parameterPolicy < 0 && r->GetValidEnd() >= start)
	  continue;
	
	gotcha.Add(r);
      }
      
      if (gotcha.GetEntries() < 1) {
	if (parameterPolicy > 0)
	  throw new BrError("BrRootCalibrationsDb::GetRevision", 
			    "No Revisions found after %d, giving up",
			    stop);
	if (parameterPolicy < 0)
	  throw new BrError("BrRootCalibrationsDb::GetRevision", 
			    "No Revisions found before %d, giving up",
			    start);
	else 
	  throw new BrFatal("BrRootCalibrationsDb::GetRevision",
			    "Something is _very_ wrong");
      }
      // In case we got one or more Revision back, we return that one
      // the first one, which is the newest because of ordering in
      // Query. 
      RevisionSort(gotcha, kFALSE, 0);
      if (parameterPolicy > 0) 
	RevisionSort(gotcha, kTRUE, 1);
      if (parameterPolicy < 0) 
	RevisionSort(gotcha, kFALSE, 2);	
      return (BrDbRevision*)gotcha.At(0);
    }
  }
  return 0;
}

//____________________________________________________________________
 void BrRootCalibrationsDb::RevisionSort(TObjArray& a, Bool_t asc,
					Int_t which) 
{
  // PRIVATE METHOD
  // Sort a TObjArray containing BrDbRevision objects, and return it
  // in itself.  
  // Parameters:
  //   a                The array 
  //   asc      kTRUE   Sort ascending
  //            kFLASE  Sort descending 
  //   which    0       Sort by date  
  //            1       Sort by validStart   
  //            2       Sort by validEnd  
  // The algorithm used is straight insertion
  if (which < 0 || which > 2) {
    Warning("RevisionSort", "invalid 'which': %d", which);
    return;
  }
  
  Int_t n = a.GetEntries();
  Int_t i, j, k;
  Int_t rd, od;
  for (i = 0; i < n; i++) {
    k = i;
    BrDbRevision* r = (BrDbRevision*)a.At(i);

    for (j = i + 1; j < n; j++) {
      switch (which) {
      case 0:
	rd = r->GetDate();
	od = ((BrDbRevision*)a.At(j))->GetDate();
	break;
      case 1:
	rd = r->GetValidStart();
	od = ((BrDbRevision*)a.At(j))->GetValidStart();
	break;
      case 2:
	rd = r->GetValidStart();
	od = ((BrDbRevision*)a.At(j))->GetValidStart();
	break;
      }
      if ((asc && rd > od) || (!asc && rd < od)) {
	k = j;
	r = (BrDbRevision*)a.At(j);
      }
    }
    
    if (k != i) {
      a.AddAt(a.At(i), k);
      a.AddAt(r,i);
    }
  }
}

//____________________________________________________________________
 BrDbRevisionType* BrRootCalibrationsDb::GetRevisionType(const Char_t* condition) 
{
  // Not implmented.  
  Warning("GetRevisionType", "not implmented");
  return 0;
}

//____________________________________________________________________
BrDbRevisionType* 
 BrRootCalibrationsDb::GetRevisionType(const Char_t* name, 
				      const Char_t* inComment) 
{
  // Query the database for a single Revision Type. The first argument
  // is the name of the revision (mandetory), and the second is a
  // string to search for in the comment field. The second arguement
  // may by "", NULL, or 0, in which case no query is perfomed on the
  // comment field. If a second argument is specified, the first
  // argument is a substring to search for. 
  if (!IsConnected())
    return 0;
  
  TString n(name);
  TString c(inComment);
  TIter next(fRevisionType);
  BrDbRevisionType* t = 0;
  while ((t = (BrDbRevisionType*)next())) {
    if (inComment && inComment[0] != '0') {
      TString c(t->GetComment());
      if (!c.Contains(inComment))
	continue;
    }
    if (n != t->GetName()) 
      continue;
    break;
  }
  return t;
}
		       
//____________________________________________________________________
// 
// EOF 
//

This page automatically generated by script docBrat by Christian Holm

Copyright ; 2002 BRAHMS Collaboration <brahmlib@rcf.rhic.bnl.gov>
Last Update on by

Validate HTML
Validate CSS