////////////////////////////////////////////////////////
//  Particle ID, properties and decay data base
//
//  
//
//                    Author: I. Froehlich
//                    Written: 11.04.2007
//                    Revised: 
//
////////////////////////////////////////////////////////


#include "PDataBase.h"
#include "TString.h"
#include "TObjArray.h"
#include "TObjString.h"
#include "TStopwatch.h"
#include "PMesh.h"

PDataBase &fDataBase() {
    static PDataBase *ans = new PDataBase();
    return *ans;
}

PDataBase *makeDataBase() {
    return &fDataBase();
}


PDataBase::PDataBase() {
    param_double_pointer = 0;
    param_string_pointer = 0;
    param_int_pointer    = 0;
    param_tobj_pointer   = 0;
    lastkey = 0;

    //Init arrays to NULL
    for (int i=0; i<PDATABASE_MAX_LINES; i++) {
	for (int j=0; j<PDATABASE_MAX_STRING_PARAM; j++)
	    strings[i][j] = NULL;
	for (int j=0; j<PDATABASE_MAX_DOUBLE_PARAM; j++)
	    doubles[i][j] = NULL;
	for (int j=0; j<PDATABASE_MAX_INT_PARAM; j++)
	    ints[i][j] = NULL;
	for (int j=0; j<PDATABASE_MAX_TOBJ_PARAM; j++)
	    tobjs[i][j] = NULL;
    }

    for (int j=0; j<PDATABASE_MAX_INT_PARAM; j++) {
	param_int_key[j] = NULL;
	param_int_key_max[j] = 0;
    }

    MakeParamString("name", "Database name"); 
//this is absolute minimum and required for testing for existence
    Info("PDataBase()", "(%s)", PRINT_CTOR);
}


void PDataBase::Print(const Option_t *) const {
    cout << param_int_pointer << " INT's booked (out of " << PDATABASE_MAX_INT_PARAM <<")" << endl;
    for (int i=0; i<param_int_pointer; i++)
	cout << "INT:" << param_int_name[i] << ":" << param_int_descr[i] << endl;

    cout << param_double_pointer << " DOUBLE's booked (out of " << PDATABASE_MAX_DOUBLE_PARAM <<")" << endl;
    for (int i=0; i<param_double_pointer; i++)
	cout << "DOUBLE:" << param_double_name[i] << ":" << param_double_descr[i] << endl;

    cout << param_string_pointer << " STRING's booked (out of " << PDATABASE_MAX_STRING_PARAM <<")" << endl;
    for (int i=0; i<param_string_pointer; i++)
	cout << "STRING:" << param_string_name[i] << ":" << param_string_descr[i] << endl;

    cout << param_tobj_pointer << " TOBJ's booked (out of " << PDATABASE_MAX_TOBJ_PARAM <<")" << endl;
    for (int i=0; i<param_tobj_pointer; i++)
	cout << "TOBJ:" << param_tobj_name[i] << ":" << param_tobj_descr[i] << endl;
    
}

void PDataBase::SetFastKey(Int_t pkey, Int_t maxkey) {
    //set if param(pkey) provides a unique fast key
    //this is the case for e.g. "pid"
    //set the maxkey to max "pid" value
    param_int_key[pkey] = new Int_t[maxkey] ;
    param_int_key_max[pkey] = maxkey;
    for (int i=0; i<maxkey; i++) 
	param_int_key[pkey][i] = -1;
}

Bool_t PDataBase::CheckEntry(Int_t key) {
    //returns a kTRUE if a line with the "key" is already initialized
    if ((key >= lastkey) || (key<-1)) return kFALSE;
    Int_t pp = 0;
    if (strings[key][pp] == NULL) return kFALSE;
    return kTRUE;

}

const char *PDataBase::GetName(Int_t key) {
    //returns the primary name
    if ((key >= lastkey) || (key<-1)) return NULL;
    Int_t pp = 0;
    return strings[key][pp];
}

Int_t PDataBase::MakeParamDouble(const char* paramname, const char *descr) {
    //check maximum size
    if (param_double_pointer == PDATABASE_MAX_DOUBLE_PARAM) {
	Fatal("MakeParamDouble", "PDATABASE_MAX_DOUBLE_PARAM reached");
    }
    //check if paramname already exists
    if (GetParamDouble(paramname) >= 0) {
	Warning("MakeParamDouble", "Value %s already exists", paramname);
	return -1;
    }
    param_double_name[param_double_pointer]  = paramname;
    param_double_descr[param_double_pointer] = descr;
    param_double_pointer++;
    return param_double_pointer-1;
}


Int_t PDataBase::MakeParamString(const char *paramname, const char *descr) {
    //check maximum size
    if (param_string_pointer == PDATABASE_MAX_STRING_PARAM) {
	Fatal("MakeParamString", "PDATABASE_MAX_STRING_PARAM reached");
    }
    //check if paramname already exists
    if (GetParamString(paramname) >= 0) {
	Warning("MakeParamString", "Value %s already exists", paramname);
	return -1;
    }
    param_string_name[param_string_pointer]  = paramname;
    param_string_descr[param_string_pointer] = descr;
    param_string_pointer++;
    return param_string_pointer-1;
}

Int_t PDataBase::MakeParamInt(const char *paramname, const char *descr) {
    //check maximum size
    if (param_int_pointer == PDATABASE_MAX_INT_PARAM) {
	Fatal("MakeParamInt", "PDATABASE_MAX_INT_PARAM reached");
    }
    //check if paramname already exists
    if (GetParamInt(paramname) >= 0) {
	Warning("MakeParamInt", "Value %s already exists", paramname);
	return -1;
    }
    param_int_name[param_int_pointer]  = paramname;
    param_int_descr[param_int_pointer] = descr;
    param_int_pointer++;
    return param_int_pointer-1;
}

Int_t PDataBase::MakeParamTObj(const char *paramname, const char *descr) {
    //check maximum size
    if (param_tobj_pointer == PDATABASE_MAX_TOBJ_PARAM) {
	Fatal("MakeParamTObj", "PDATABASE_MAX_TOBJ_PARAM reached");
    }
    //check if paramname already exists
    if (GetParamTObj(paramname) >= 0) {
	Warning("MakeParamTObj", "Value %s already exists", paramname);
	return -1;
    }
    param_tobj_name[param_tobj_pointer]  = paramname;
    param_tobj_descr[param_tobj_pointer] = descr;
    param_tobj_pointer++;
    return  param_tobj_pointer-1;
}

Int_t PDataBase ::GetParamDouble(const char* paramname) {
    for (int i=0; i<param_double_pointer; i++)
	if (strcmp(paramname,param_double_name[i])==0) return i;
    return -1;
}

Int_t PDataBase::GetParamString(const char *paramname) {
    //BUGBUG: If paramname is a pointer like "d1:name" this does not work->write getDescription
    for (int i=0; i<param_string_pointer; i++)
	if (strcmp(paramname,param_string_name[i]) == 0) return i;
    return -1;
}

Int_t PDataBase ::GetParamInt(const char *paramname, Int_t length) {
    for (int i=0; i<param_int_pointer; i++) {
	if (length<0) {
	    if (strcmp(paramname,param_int_name[i]) == 0) return i;
	} else {
	    if (strncmp(paramname,param_int_name[i],length) == 0) return i;
	}
    }
    return -1;    
}

Int_t PDataBase::GetParamTObj(const char* paramname) {
    for (int i=0; i<param_tobj_pointer; i++)
	if (strcmp(paramname,param_tobj_name[i]) == 0) return i;
    return -1;
}

Int_t  PDataBase::ConvertParamKey(const char * &newparamname, Int_t key) {
    //checks for the ":" delmiter, sets the pointer to the remaing string
    //evaluate the new key
    //cout << "newparamname init " <<newparamname << endl;
    Int_t *newkey;
    for (unsigned int i=0; i<strlen(newparamname); i++) {
	if (newparamname[i] == ':') {
	    if (!GetParamInt(key, newparamname, &newkey, i)) {
		Warning("ConvertParamKey", "Value %s for key %i not existing", newparamname, key);
		return -1;
	    }
	    newparamname = newparamname + i + 1;

	    return *newkey;
	}	
    }
    return -1;
}

char *PDataBase::GetDescription(const char *paramname) {
    //Interpretation of pattern
    TString spattern(paramname);
    TObjArray *array = spattern.Tokenize(TString(":"));
    TString bla;
    Int_t done = 0;
    for (int pat=0; pat<array->GetEntriesFast(); pat++) {
	if (done) bla.Append("->");
	TObjString *patoption = (TObjString *) (*array)[pat];
	char *options = (char*)patoption->GetString().Data();
	if (GetParamString(options) > -1) {
	    bla.Append(param_string_descr[GetParamString(options)]);
	    done = 1;
	}
	if (GetParamInt(options) > -1) {
	    bla.Append(param_int_descr[GetParamInt(options)]);
	    done = 1;
	}
	if (GetParamDouble(options) > -1) {
	    bla.Append(param_double_descr[GetParamDouble(options)]);
	    done = 1;
	}
	if (GetParamTObj(options) > -1) {
	    bla.Append(param_tobj_descr[GetParamTObj(options)]);
	    done = 1;
	}
    }
    char *dummy = new char[strlen(bla.Data())+2];
    strcpy(dummy, bla.Data());
    return dummy; //receiver must call delete
}

Bool_t PDataBase::GetParamDouble(Int_t key, const char *paramname, Double_t **result) {
    //return kFALSE if 1.) key not existing or 2.) Param not existing or 3.) Param not used for key
    if (!CheckEntry(key)) return kFALSE;
    Int_t newkey = -1;
    const char *newparamname = paramname;

    if ((newkey = ConvertParamKey(newparamname,key))>=0) {
	return GetParamDouble(newkey, newparamname, result);
    }
    paramname = newparamname;
    Int_t pp = GetParamDouble(paramname);
    if (pp<0) return kFALSE;

    if (doubles[key][pp] == NULL) return kFALSE;

    *result = doubles[key][pp];
    return kTRUE;
}

Bool_t PDataBase::GetParamDouble(Int_t key, Int_t pkey, Double_t **result) {
    if (!CheckEntry(key)) return kFALSE;
    if (pkey < 0) return kFALSE;
    if (doubles[key][pkey] == NULL) return kFALSE;
    *result = doubles[key][pkey];
    return kTRUE;
}


Bool_t PDataBase::GetParamString(Int_t key, const char *paramname, const char **result) {
    //return kFALSE if 1.) KEY not existing or 2.) Param not existing or 3.) Param not used for KEY
    if (!CheckEntry(key)) return kFALSE;
    Int_t newkey = -1;
    const char *newparamname = paramname;

    if ((newkey = ConvertParamKey(newparamname,key))>=0) {
	return GetParamString(newkey,newparamname,result);
    }
    paramname = newparamname;
    Int_t pp = GetParamString(paramname);
    if (pp<0) return kFALSE;

    if (strings[key][pp] == NULL) return kFALSE;

    *result = strings[key][pp];
    return kTRUE;
}

Bool_t PDataBase::GetParamString(Int_t key, Int_t pkey, const char **result) {
    if (!CheckEntry(key)) return kFALSE;
    if (pkey<0) return kFALSE;
    if (strings[key][pkey] == NULL) return kFALSE;
    *result = strings[key][pkey];
    return kTRUE;
}

Bool_t PDataBase::GetParamInt(Int_t key, const char *paramname, Int_t **result, Int_t length) {
    //return kFALSE if 1.) key not existing or 2.) Param not existing or 3.) Param not used for key
    if (!CheckEntry(key)) return kFALSE;

    Int_t newkey = -1;
    const char *newparamname = paramname;
    if (length < 0) {
	if ((newkey = ConvertParamKey(newparamname,key))>=0) {
	    return GetParamInt(newkey, newparamname, result);
	}
    }
    paramname = newparamname;
    Int_t pp = GetParamInt(paramname, length);
    if (pp < 0) 
	return kFALSE;
    
    if (ints[key][pp] == NULL) return kFALSE;

    *result = ints[key][pp];
    return kTRUE;
}

Bool_t PDataBase::GetParamInt(Int_t key, Int_t pkey, Int_t **result) {
    if (!CheckEntry(key)) return kFALSE;

    if (pkey < 0) return kFALSE;
    if (ints[key][pkey] == NULL) return kFALSE;
    *result = ints[key][pkey];
    return kTRUE;
}

Bool_t PDataBase::GetParamTObj(Int_t key, const char *paramname, TObject **result) {
    //return kFALSE if 1.) KEY not existing or 2.) Param not existing or 3.) Param not used for KEY
    if (!CheckEntry(key)) return kFALSE;
    Int_t newkey = -1;
    const char *newparamname = paramname;

    if ((newkey = ConvertParamKey(newparamname,key)) >= 0) {
	return GetParamTObj(newkey,newparamname,result);
    }
    paramname = newparamname;
    Int_t pp  = GetParamTObj(paramname);
    if (pp < 0) return kFALSE;

    if (tobjs[key][pp] == NULL) return kFALSE;

    *result = tobjs[key][pp];
    return kTRUE;
}

Bool_t PDataBase::GetParamTObj(Int_t key, Int_t pkey, TObject **result) {
    if (!CheckEntry(key)) return kFALSE;
    if (pkey < 0) return kFALSE;
    if (tobjs[key][pkey] == NULL) return kFALSE;
    *result = tobjs[key][pkey];
    return kTRUE;
}

Bool_t PDataBase::SetParamDouble(Int_t key, const char *paramname, Double_t *result) {
    //return kFALSE if 1.) KEY not existing or 2.) Param not existing or 3.) Param not used for KEY
    if (!CheckEntry(key)) {
	Error("SetParamDouble", "key %i not existing", key);
	return kFALSE;
    }
    
    Int_t pp = GetParamDouble(paramname);
    if (pp < 0) {
	Error("SetParamDouble", "paramname %s not existing", paramname);
	return kFALSE;
    }

    doubles[key][pp] = result;
    return kTRUE;
}

Bool_t PDataBase::SetParamString (Int_t key, const char *paramname, char *result) {
    //return kFALSE if 1.) KEY not existing or 2.) Param not existing or 3.) Param not used for KEY
    if (!CheckEntry(key)) {
	Error("SetParamString", "key %i not existing", key);
	return kFALSE;
    }
    
    Int_t pp = GetParamString(paramname);
    if (pp < 0) {
	Error("SetParamString", "paramname %s not existing", paramname);
	return kFALSE;
    }

    strings[key][pp] = result;
    return kTRUE;
}

Bool_t PDataBase::SetParamInt (Int_t key, const char *paramname, Int_t *result) {
    //return kFALSE if 1.) KEY not existing or 2.) Param not existing or 3.) Param not used for KEY
    if (!CheckEntry(key)) {
	Error("SetParamInt", "key %i not existing", key);
	return kFALSE;
    }
    
    Int_t pp = GetParamInt(paramname);
    if (pp < 0) {
	Error("SetParamInt", "paramname %s not existing", paramname);
	return kFALSE;
    }

    ints[key][pp] = result;
    return kTRUE;
}

Bool_t PDataBase::SetParamTObj(Int_t key, const char *paramname, TObject *result) {
    //return kFALSE if 1.) KEY not existing or 2.) Param not existing or 3.) Param not used for KEY
    if (!CheckEntry(key)) {
	Error("SetParamTObj", "key %i not existing", key);
	return kFALSE;
    }
    
    Int_t pp = GetParamTObj(paramname);
    if (pp < 0) {
	Error("SetParamTObj", "paramname %s not existing", paramname);
	return kFALSE;
    }

    tobjs[key][pp] = result;
    return kTRUE;
}

Bool_t PDataBase::SetParamTObj(Int_t key, Int_t pp, TObject *result) {
    //return kFALSE if 1.) KEY not existing or 2.) Param not existing or 3.) Param not used for KEY
    if (!CheckEntry(key)) {
	Error("SetParamTObj", "key %i not existing", key);
	return kFALSE;
    }
    
    tobjs[key][pp] = result;
    return kTRUE;
}

Int_t PDataBase::GetEntry(const char *name) {
    for (int i=0; i<lastkey; i++) {
	if (strings[i][0])
	    if (strcmp(name,strings[i][0]) == 0) return i;
    }
    return -1;	
}

Int_t PDataBase::GetEntryInt(const char *paramname, Int_t value) {
    Int_t *result;
    for (int i=0; i<lastkey; i++) {
	if (GetParamInt (i, paramname,&result)) {
	    if (*result == value)
		return i;
	}
    }
    return -1;
}

Int_t PDataBase::GetEntryInt(Int_t pkey, Int_t value) {
//return the index key if param(pkey) is matching the value
//otherwise -1
    Int_t *result;

    //use fast checking is available
    if (param_int_key[pkey]) {
	if ((value>=0) && (value<param_int_key_max[pkey])) {
	    if (param_int_key[pkey][value] != -1) {
		return param_int_key[pkey][value];
	    } else {
		for (int i=0; i<lastkey; i++) {
		    if (GetParamInt (i, pkey,&result)) {
			if (*result == value) {
			    param_int_key[pkey][value] = i;
			    return i;
			}
		    }
		}
	    }
	}
    }

    //slow version: loop over entries
    for (int i=0; i<lastkey; i++) {
	if (GetParamInt (i, pkey, &result)) {
	    if (*result == value)
		return i;
	}
    }
    return -1;
}

Bool_t PDataBase::AddEntry(Int_t key, const char *name) {
    if (CheckEntry(key)) {
	Warning("AddEntry", "Key %i already existing", key);
	return kFALSE;
    }
    if (GetEntry(name) >=0) {
	Warning("AddEntry", "An entry with name %s already exists", name);
	return kFALSE;
    }
    Int_t pp = GetParamString("name");
    strings[key][pp] = name;
    return kTRUE;
}

Int_t PDataBase::AddEntry(const char *name) {
    if (AddEntry(lastkey, name)) {
	lastkey++;
	return lastkey-1;
    }
    return -1;
}

Int_t PDataBase::AddListEntry(const char *name, const char *count, 
			      const char *link, const char *newname) {
    //This is used to add linked-lists the the entry "name"
    //The "count" (which should be an int param) holds the number of links
    //"link" is used for:
    //1.) setting the key to the last entry of the lists (updated on the fly)
    //2.) setting the key from the last list entry to the last-but-one
    //The first list entry points back to the original "name", thus forming a ring
    //"newname" is the name of the new list entry

    Int_t *i_count;
    Int_t *i_link;
    Int_t *i_newlink;
    Int_t key = GetEntry(name);
    Int_t targetkey = GetEntry(newname);
    if (key < 0) {
	Warning("AddListEntry","Unable to get entry %s",name);
	return -1;
    }

    //test if linked list already initialized
    if (!GetParamInt (key, count, &i_count)) {
	//initialize
	//first add the new entry before modifying the old one
	if (targetkey < 0) targetkey = AddEntry(newname);
	if (targetkey < 0) {
	    Warning("AddListEntry", "Unable to name entry %s", newname);
	    return -1;
	}
	//if this worked, set the link from the new to the old entry
	//TODO: More consitency checks

	i_count = new Int_t(1);
	SetParamInt(key, count, i_count);
	i_link  = new Int_t(targetkey);
	SetParamInt(key, link, i_link);
	i_newlink= new Int_t(key);
	SetParamInt(targetkey, link, i_newlink);
    } else {
	//first add the new entry before modifying the old one
	if (targetkey < 0) targetkey = AddEntry(newname);
	if (targetkey < 0) {
	    Warning("AddListEntry","Unable to name entry %s",newname);
	    return -1;
	}
	//increment target count
	GetParamInt(key, count,&i_count);
	(*i_count)++;

	//Find the last entry in the chain
	Int_t listkey=-1, mylastkey=-1;
	while (makeDataBase()->MakeListIterator(key, count, link, &listkey)) {
	    mylastkey = listkey;
	}

	//copy old pointer to new entry
	//GetParamInt (key, link,&i_link);
	GetParamInt(mylastkey, link, &i_link);
	i_newlink = new Int_t(*i_link);
	SetParamInt(targetkey, link, i_newlink);
	//set new entry
	i_link = new Int_t(targetkey);
	SetParamInt(mylastkey, link, i_link);
    }
    return targetkey;
}

Bool_t PDataBase::MakeListIterator(Int_t key, const char *count, 
				   const char *link, Int_t *listkey) {
    //get the list entries which belongs to "key" and is described by "counts" and "link"
    //(both has to be defined in a proper way)
    //It is very important that on the 1st call *listkey is -1
    //on the value kTRUE, *listkey contains the key link to the list entry
    //on the value kFALSE, the iteration has been finished (or not started due to an error)
    Int_t *i_count, *loc_listkey_p;
    
    if (key == -1) return kFALSE;
    if (*listkey ==- 1) { //first call: check list header entry
	if (count) {
	    if (!GetParamInt (key, count, &i_count)) {
		Warning("MakeListIterator", "count %s not found", count);
		return kFALSE;
	    }
	}
	if (!GetParamInt (key, link, &loc_listkey_p)) {
	    Warning("MakeListIterator", "link %s not found", link);
	    return kFALSE;
	}
    } else {
	if (!GetParamInt (*listkey, link, &loc_listkey_p)) return kFALSE;
    }
    //now copy to external
    *listkey = *loc_listkey_p;
    if (*listkey == key) {
	*listkey = -1;
	return kFALSE;
    }
    return kTRUE;
}

Bool_t PDataBase::MakeListIterator(Int_t key, Int_t count, Int_t link, Int_t *listkey) {
    //get the list entries which belongs to "key" and is described by "counts" and "link"
    //(both has to be defined in a proper way)
    //It is very important that on the 1st call *listkey is -1
    //on the value kTRUE, *listkey contains the key link to the list entry
    //on the value kFALSE, the iteration has been finished (or not started due to an error)
    Int_t *i_count, *loc_listkey_p;
    
    if (key == -1) return kFALSE;
    if (*listkey == -1) { //first call: check list header entry
	if (count >= 0) {
	    if (!GetParamInt(key, count,&i_count)) {
		Warning("MakeListIterator", "count %i not found", count);
		return kFALSE;
	    }
	}
	if (!GetParamInt(key, link, &loc_listkey_p)) {
	    Warning("MakeListIterator", "link %i not found", link);
	    return kFALSE;
	}
    } else {
	if (!GetParamInt (*listkey, link, &loc_listkey_p)) return kFALSE;
    }
    //now copy to external
    *listkey = *loc_listkey_p;
    if (*listkey == key) {
	*listkey =  -1;
	return kFALSE;
    }
    return kTRUE;
}

Bool_t PDataBase::ListEntries(Int_t key, Int_t option, const char *pattern) {
    //key=line (or -1 for all)
    //option=0 : line break =1: no line break
    //pattern like "mass,width"
    
    Int_t start = 0;
    Int_t end   = PDATABASE_MAX_LINES-1;
    Double_t   *result;
    const char *result2;
    Int_t   *result3;
    TObject *result4;
    Int_t sz[PDATABASE_MAX_LINES][PDATABASE_MAX_DOUBLE_PARAM+PDATABASE_MAX_STRING_PARAM]; 
    Int_t max_sz[PDATABASE_MAX_DOUBLE_PARAM+PDATABASE_MAX_STRING_PARAM]; 
    Int_t valid_key[PDATABASE_MAX_LINES];

    for (int i=0; i<(PDATABASE_MAX_DOUBLE_PARAM+PDATABASE_MAX_STRING_PARAM); i++) {
	max_sz[i]=0;
	for (int j=0; j<PDATABASE_MAX_LINES; j++) {
	    sz[j][i]=0;
	    valid_key[j]=0;
	}
    }

    //Interpretation of pattern
    TString spattern(pattern);
    TObjArray *array = spattern.Tokenize(TString(","));

    if (key >= 0) {start=end=key;}
    for (int run=0; run<2; run++) {
	//run0: check size etc.
	//run1: print info
	for (int i=start; i<=end; i++) {
	    //TODO: check if at least one param is there
	    if (run && valid_key[i]>0) { 
		if (option) {
		    cout << i << ":";
		    if (i<10) cout << " ";
		    if (i<100) cout << " ";
		    if (i<1000) cout << " ";
		} else {
		    cout << "Database key=" << i << endl;
		}
	    }
	    for (int pat=0; pat<array->GetEntriesFast(); pat++) {
		if (pat >= (PDATABASE_MAX_DOUBLE_PARAM+
			    PDATABASE_MAX_STRING_PARAM+
			    PDATABASE_MAX_INT_PARAM+
			    PDATABASE_MAX_TOBJ_PARAM)) {
		    //Too many string->Something is wrong
		    Warning("listEntries", "Too many pattern strings");
		    return kFALSE;
		}
		TObjString *patoption = (TObjString *) (*array)[pat];
		char *options = (char*)patoption->GetString().Data();
		Bool_t checkline = kTRUE;
		Bool_t invert    = kFALSE;
		if (options[0] == '*') {
		    //check paramteter, but not used for line selection
		    options++;
		    checkline = kFALSE;
		}
		if (options[0] == '!') { 
		    options++;
		    invert = kTRUE;
		}

		if (GetParamDouble (i, options, &result)) {
		    if (run) {
			if (valid_key[i]>0) {	   
			    if (option) cout << options <<  "=";
			    else  cout << GetDescription(options) <<  "=";
			    printf("%f", *result);
			    if (option) cout << " "; 
			    else        cout << " \n";
			}
		    } else {
			char bla[1000]; //I dont know a better way to get the length
			// (if somebody has an idea -> help yourself)
			sprintf(bla, "%f", *result);
			sz[i][pat] = strlen(bla);
			if (sz[i][pat] > max_sz[pat]) 
			    max_sz[pat] = sz[i][pat];
			if (checkline && !invert) 
			    valid_key[i]++;
			else if (invert && checkline) 
			    valid_key[i] = -999;
		    }
		} else if (GetParamInt (i, options, &result3)) {
		    if (run) {
			if (valid_key[i]>0) {
			    if (option) 
				cout << options <<  "=";
			    else  
				cout << GetDescription(options) <<  "=";
			    printf("%i", *result3);
			    if (option) 
				 cout << " "; 
			    else cout << " \n";
			}
		    } else {
			char bla[1000]; //I dont know a better way to get the length
			// (if somebody has an idea -> help yourself)
			sprintf(bla, "%i", *result3);
			sz[i][pat] = strlen(bla);
			if (sz[i][pat] > max_sz[pat]) 
			    max_sz[pat] = sz[i][pat];
			if (checkline && !invert) 
			    valid_key[i]++;
			else if (invert && checkline) 
			    valid_key[i] = -999;
		    }
		} else if (GetParamString (i, options, &result2)) {
		    if (run) {
			if (valid_key[i] > 0) {
			    if (option) 
				cout << options << "=" << result2;
			    else 
				cout << GetDescription(options) << "="<< result2;
			    if (option) cout << " "; 
			    else        cout << " \n";
			}
		    } else {
			sz[i][pat] = strlen(result2);
			if (sz[i][pat] > max_sz[pat]) 
			    max_sz[pat] = sz[i][pat];
			if (checkline && !invert) 
			    valid_key[i]++;
			else if (invert && checkline) 
			    valid_key[i] = -999;
		    }
		} else if (GetParamTObj (i, options,&result4)) {
		    if (run) {
			if (valid_key[i]>0) {
			   
			    if (option) 
				cout << options << "=<yes>";
			    else 
				cout << GetDescription(options) << "=<yes>";
			    if (option) cout << " "; 
			    else        cout << " \n";
			}
		    } else {
			sz[i][pat] = 4; //for the yes
			if (sz[i][pat] > max_sz[pat]) 
			    max_sz[pat] = sz[i][pat];
			if (checkline && !invert) 
			    valid_key[i]++;
			else if (invert && checkline) 
			    valid_key[i] = -999;
		    }
		} 
		 
		if (option && run && valid_key[i]>0) {
		    //fill missing gaps
		    int ga = sz[i][pat];
		    //account for missing option string
		    if (!ga) ga -= strlen(options)+2;
		    for (int x=ga; x<max_sz[pat]; x++) {
			cout << " ";
		    }
		}
	    }
	     
	    if (run && valid_key[i]>0) cout << "\n"; 
	}
    }
    delete array;
    return kTRUE;
}

void PDataBase::Performance(void) {
    TStopwatch timer;
    //way1: loop over pids, and get the name
    timer.Start();
    Int_t mypid=0, pid_param=0, *i_result;
    for (int r=0; r<10000; r++)
	for (int i=0; i<50; i++) {
	    //get the pid from name
	    int k = 0;
	    for (k=0; (k<50) && strcmp(strings[i][0],strings[k][0]); k++) {
	    }
	    mypid += k;
	}
    cout << timer.RealTime() << endl;
    cout << mypid << endl;
    mypid = 0;

    timer.Start();
    //now the new way
    for (int r=0; r<10000; r++)
	for (int i=0; i<50; i++) {
	    GetFastParamInt("pid", &pid_param);
	    if (!GetParamInt(GetEntry(strings[i][0]), pid_param, &i_result)) {
//	    if (!getFastParamInt (pid_param,i, &i_result)) {
		Error("Performance", "ID %i not found", i);	
	    } 
	    mypid += *i_result;
	}
    cout << timer.RealTime() << endl;
    cout << mypid << endl;
}


ClassImp(PDataBase)
 PDataBase.cc:1
 PDataBase.cc:2
 PDataBase.cc:3
 PDataBase.cc:4
 PDataBase.cc:5
 PDataBase.cc:6
 PDataBase.cc:7
 PDataBase.cc:8
 PDataBase.cc:9
 PDataBase.cc:10
 PDataBase.cc:11
 PDataBase.cc:12
 PDataBase.cc:13
 PDataBase.cc:14
 PDataBase.cc:15
 PDataBase.cc:16
 PDataBase.cc:17
 PDataBase.cc:18
 PDataBase.cc:19
 PDataBase.cc:20
 PDataBase.cc:21
 PDataBase.cc:22
 PDataBase.cc:23
 PDataBase.cc:24
 PDataBase.cc:25
 PDataBase.cc:26
 PDataBase.cc:27
 PDataBase.cc:28
 PDataBase.cc:29
 PDataBase.cc:30
 PDataBase.cc:31
 PDataBase.cc:32
 PDataBase.cc:33
 PDataBase.cc:34
 PDataBase.cc:35
 PDataBase.cc:36
 PDataBase.cc:37
 PDataBase.cc:38
 PDataBase.cc:39
 PDataBase.cc:40
 PDataBase.cc:41
 PDataBase.cc:42
 PDataBase.cc:43
 PDataBase.cc:44
 PDataBase.cc:45
 PDataBase.cc:46
 PDataBase.cc:47
 PDataBase.cc:48
 PDataBase.cc:49
 PDataBase.cc:50
 PDataBase.cc:51
 PDataBase.cc:52
 PDataBase.cc:53
 PDataBase.cc:54
 PDataBase.cc:55
 PDataBase.cc:56
 PDataBase.cc:57
 PDataBase.cc:58
 PDataBase.cc:59
 PDataBase.cc:60
 PDataBase.cc:61
 PDataBase.cc:62
 PDataBase.cc:63
 PDataBase.cc:64
 PDataBase.cc:65
 PDataBase.cc:66
 PDataBase.cc:67
 PDataBase.cc:68
 PDataBase.cc:69
 PDataBase.cc:70
 PDataBase.cc:71
 PDataBase.cc:72
 PDataBase.cc:73
 PDataBase.cc:74
 PDataBase.cc:75
 PDataBase.cc:76
 PDataBase.cc:77
 PDataBase.cc:78
 PDataBase.cc:79
 PDataBase.cc:80
 PDataBase.cc:81
 PDataBase.cc:82
 PDataBase.cc:83
 PDataBase.cc:84
 PDataBase.cc:85
 PDataBase.cc:86
 PDataBase.cc:87
 PDataBase.cc:88
 PDataBase.cc:89
 PDataBase.cc:90
 PDataBase.cc:91
 PDataBase.cc:92
 PDataBase.cc:93
 PDataBase.cc:94
 PDataBase.cc:95
 PDataBase.cc:96
 PDataBase.cc:97
 PDataBase.cc:98
 PDataBase.cc:99
 PDataBase.cc:100
 PDataBase.cc:101
 PDataBase.cc:102
 PDataBase.cc:103
 PDataBase.cc:104
 PDataBase.cc:105
 PDataBase.cc:106
 PDataBase.cc:107
 PDataBase.cc:108
 PDataBase.cc:109
 PDataBase.cc:110
 PDataBase.cc:111
 PDataBase.cc:112
 PDataBase.cc:113
 PDataBase.cc:114
 PDataBase.cc:115
 PDataBase.cc:116
 PDataBase.cc:117
 PDataBase.cc:118
 PDataBase.cc:119
 PDataBase.cc:120
 PDataBase.cc:121
 PDataBase.cc:122
 PDataBase.cc:123
 PDataBase.cc:124
 PDataBase.cc:125
 PDataBase.cc:126
 PDataBase.cc:127
 PDataBase.cc:128
 PDataBase.cc:129
 PDataBase.cc:130
 PDataBase.cc:131
 PDataBase.cc:132
 PDataBase.cc:133
 PDataBase.cc:134
 PDataBase.cc:135
 PDataBase.cc:136
 PDataBase.cc:137
 PDataBase.cc:138
 PDataBase.cc:139
 PDataBase.cc:140
 PDataBase.cc:141
 PDataBase.cc:142
 PDataBase.cc:143
 PDataBase.cc:144
 PDataBase.cc:145
 PDataBase.cc:146
 PDataBase.cc:147
 PDataBase.cc:148
 PDataBase.cc:149
 PDataBase.cc:150
 PDataBase.cc:151
 PDataBase.cc:152
 PDataBase.cc:153
 PDataBase.cc:154
 PDataBase.cc:155
 PDataBase.cc:156
 PDataBase.cc:157
 PDataBase.cc:158
 PDataBase.cc:159
 PDataBase.cc:160
 PDataBase.cc:161
 PDataBase.cc:162
 PDataBase.cc:163
 PDataBase.cc:164
 PDataBase.cc:165
 PDataBase.cc:166
 PDataBase.cc:167
 PDataBase.cc:168
 PDataBase.cc:169
 PDataBase.cc:170
 PDataBase.cc:171
 PDataBase.cc:172
 PDataBase.cc:173
 PDataBase.cc:174
 PDataBase.cc:175
 PDataBase.cc:176
 PDataBase.cc:177
 PDataBase.cc:178
 PDataBase.cc:179
 PDataBase.cc:180
 PDataBase.cc:181
 PDataBase.cc:182
 PDataBase.cc:183
 PDataBase.cc:184
 PDataBase.cc:185
 PDataBase.cc:186
 PDataBase.cc:187
 PDataBase.cc:188
 PDataBase.cc:189
 PDataBase.cc:190
 PDataBase.cc:191
 PDataBase.cc:192
 PDataBase.cc:193
 PDataBase.cc:194
 PDataBase.cc:195
 PDataBase.cc:196
 PDataBase.cc:197
 PDataBase.cc:198
 PDataBase.cc:199
 PDataBase.cc:200
 PDataBase.cc:201
 PDataBase.cc:202
 PDataBase.cc:203
 PDataBase.cc:204
 PDataBase.cc:205
 PDataBase.cc:206
 PDataBase.cc:207
 PDataBase.cc:208
 PDataBase.cc:209
 PDataBase.cc:210
 PDataBase.cc:211
 PDataBase.cc:212
 PDataBase.cc:213
 PDataBase.cc:214
 PDataBase.cc:215
 PDataBase.cc:216
 PDataBase.cc:217
 PDataBase.cc:218
 PDataBase.cc:219
 PDataBase.cc:220
 PDataBase.cc:221
 PDataBase.cc:222
 PDataBase.cc:223
 PDataBase.cc:224
 PDataBase.cc:225
 PDataBase.cc:226
 PDataBase.cc:227
 PDataBase.cc:228
 PDataBase.cc:229
 PDataBase.cc:230
 PDataBase.cc:231
 PDataBase.cc:232
 PDataBase.cc:233
 PDataBase.cc:234
 PDataBase.cc:235
 PDataBase.cc:236
 PDataBase.cc:237
 PDataBase.cc:238
 PDataBase.cc:239
 PDataBase.cc:240
 PDataBase.cc:241
 PDataBase.cc:242
 PDataBase.cc:243
 PDataBase.cc:244
 PDataBase.cc:245
 PDataBase.cc:246
 PDataBase.cc:247
 PDataBase.cc:248
 PDataBase.cc:249
 PDataBase.cc:250
 PDataBase.cc:251
 PDataBase.cc:252
 PDataBase.cc:253
 PDataBase.cc:254
 PDataBase.cc:255
 PDataBase.cc:256
 PDataBase.cc:257
 PDataBase.cc:258
 PDataBase.cc:259
 PDataBase.cc:260
 PDataBase.cc:261
 PDataBase.cc:262
 PDataBase.cc:263
 PDataBase.cc:264
 PDataBase.cc:265
 PDataBase.cc:266
 PDataBase.cc:267
 PDataBase.cc:268
 PDataBase.cc:269
 PDataBase.cc:270
 PDataBase.cc:271
 PDataBase.cc:272
 PDataBase.cc:273
 PDataBase.cc:274
 PDataBase.cc:275
 PDataBase.cc:276
 PDataBase.cc:277
 PDataBase.cc:278
 PDataBase.cc:279
 PDataBase.cc:280
 PDataBase.cc:281
 PDataBase.cc:282
 PDataBase.cc:283
 PDataBase.cc:284
 PDataBase.cc:285
 PDataBase.cc:286
 PDataBase.cc:287
 PDataBase.cc:288
 PDataBase.cc:289
 PDataBase.cc:290
 PDataBase.cc:291
 PDataBase.cc:292
 PDataBase.cc:293
 PDataBase.cc:294
 PDataBase.cc:295
 PDataBase.cc:296
 PDataBase.cc:297
 PDataBase.cc:298
 PDataBase.cc:299
 PDataBase.cc:300
 PDataBase.cc:301
 PDataBase.cc:302
 PDataBase.cc:303
 PDataBase.cc:304
 PDataBase.cc:305
 PDataBase.cc:306
 PDataBase.cc:307
 PDataBase.cc:308
 PDataBase.cc:309
 PDataBase.cc:310
 PDataBase.cc:311
 PDataBase.cc:312
 PDataBase.cc:313
 PDataBase.cc:314
 PDataBase.cc:315
 PDataBase.cc:316
 PDataBase.cc:317
 PDataBase.cc:318
 PDataBase.cc:319
 PDataBase.cc:320
 PDataBase.cc:321
 PDataBase.cc:322
 PDataBase.cc:323
 PDataBase.cc:324
 PDataBase.cc:325
 PDataBase.cc:326
 PDataBase.cc:327
 PDataBase.cc:328
 PDataBase.cc:329
 PDataBase.cc:330
 PDataBase.cc:331
 PDataBase.cc:332
 PDataBase.cc:333
 PDataBase.cc:334
 PDataBase.cc:335
 PDataBase.cc:336
 PDataBase.cc:337
 PDataBase.cc:338
 PDataBase.cc:339
 PDataBase.cc:340
 PDataBase.cc:341
 PDataBase.cc:342
 PDataBase.cc:343
 PDataBase.cc:344
 PDataBase.cc:345
 PDataBase.cc:346
 PDataBase.cc:347
 PDataBase.cc:348
 PDataBase.cc:349
 PDataBase.cc:350
 PDataBase.cc:351
 PDataBase.cc:352
 PDataBase.cc:353
 PDataBase.cc:354
 PDataBase.cc:355
 PDataBase.cc:356
 PDataBase.cc:357
 PDataBase.cc:358
 PDataBase.cc:359
 PDataBase.cc:360
 PDataBase.cc:361
 PDataBase.cc:362
 PDataBase.cc:363
 PDataBase.cc:364
 PDataBase.cc:365
 PDataBase.cc:366
 PDataBase.cc:367
 PDataBase.cc:368
 PDataBase.cc:369
 PDataBase.cc:370
 PDataBase.cc:371
 PDataBase.cc:372
 PDataBase.cc:373
 PDataBase.cc:374
 PDataBase.cc:375
 PDataBase.cc:376
 PDataBase.cc:377
 PDataBase.cc:378
 PDataBase.cc:379
 PDataBase.cc:380
 PDataBase.cc:381
 PDataBase.cc:382
 PDataBase.cc:383
 PDataBase.cc:384
 PDataBase.cc:385
 PDataBase.cc:386
 PDataBase.cc:387
 PDataBase.cc:388
 PDataBase.cc:389
 PDataBase.cc:390
 PDataBase.cc:391
 PDataBase.cc:392
 PDataBase.cc:393
 PDataBase.cc:394
 PDataBase.cc:395
 PDataBase.cc:396
 PDataBase.cc:397
 PDataBase.cc:398
 PDataBase.cc:399
 PDataBase.cc:400
 PDataBase.cc:401
 PDataBase.cc:402
 PDataBase.cc:403
 PDataBase.cc:404
 PDataBase.cc:405
 PDataBase.cc:406
 PDataBase.cc:407
 PDataBase.cc:408
 PDataBase.cc:409
 PDataBase.cc:410
 PDataBase.cc:411
 PDataBase.cc:412
 PDataBase.cc:413
 PDataBase.cc:414
 PDataBase.cc:415
 PDataBase.cc:416
 PDataBase.cc:417
 PDataBase.cc:418
 PDataBase.cc:419
 PDataBase.cc:420
 PDataBase.cc:421
 PDataBase.cc:422
 PDataBase.cc:423
 PDataBase.cc:424
 PDataBase.cc:425
 PDataBase.cc:426
 PDataBase.cc:427
 PDataBase.cc:428
 PDataBase.cc:429
 PDataBase.cc:430
 PDataBase.cc:431
 PDataBase.cc:432
 PDataBase.cc:433
 PDataBase.cc:434
 PDataBase.cc:435
 PDataBase.cc:436
 PDataBase.cc:437
 PDataBase.cc:438
 PDataBase.cc:439
 PDataBase.cc:440
 PDataBase.cc:441
 PDataBase.cc:442
 PDataBase.cc:443
 PDataBase.cc:444
 PDataBase.cc:445
 PDataBase.cc:446
 PDataBase.cc:447
 PDataBase.cc:448
 PDataBase.cc:449
 PDataBase.cc:450
 PDataBase.cc:451
 PDataBase.cc:452
 PDataBase.cc:453
 PDataBase.cc:454
 PDataBase.cc:455
 PDataBase.cc:456
 PDataBase.cc:457
 PDataBase.cc:458
 PDataBase.cc:459
 PDataBase.cc:460
 PDataBase.cc:461
 PDataBase.cc:462
 PDataBase.cc:463
 PDataBase.cc:464
 PDataBase.cc:465
 PDataBase.cc:466
 PDataBase.cc:467
 PDataBase.cc:468
 PDataBase.cc:469
 PDataBase.cc:470
 PDataBase.cc:471
 PDataBase.cc:472
 PDataBase.cc:473
 PDataBase.cc:474
 PDataBase.cc:475
 PDataBase.cc:476
 PDataBase.cc:477
 PDataBase.cc:478
 PDataBase.cc:479
 PDataBase.cc:480
 PDataBase.cc:481
 PDataBase.cc:482
 PDataBase.cc:483
 PDataBase.cc:484
 PDataBase.cc:485
 PDataBase.cc:486
 PDataBase.cc:487
 PDataBase.cc:488
 PDataBase.cc:489
 PDataBase.cc:490
 PDataBase.cc:491
 PDataBase.cc:492
 PDataBase.cc:493
 PDataBase.cc:494
 PDataBase.cc:495
 PDataBase.cc:496
 PDataBase.cc:497
 PDataBase.cc:498
 PDataBase.cc:499
 PDataBase.cc:500
 PDataBase.cc:501
 PDataBase.cc:502
 PDataBase.cc:503
 PDataBase.cc:504
 PDataBase.cc:505
 PDataBase.cc:506
 PDataBase.cc:507
 PDataBase.cc:508
 PDataBase.cc:509
 PDataBase.cc:510
 PDataBase.cc:511
 PDataBase.cc:512
 PDataBase.cc:513
 PDataBase.cc:514
 PDataBase.cc:515
 PDataBase.cc:516
 PDataBase.cc:517
 PDataBase.cc:518
 PDataBase.cc:519
 PDataBase.cc:520
 PDataBase.cc:521
 PDataBase.cc:522
 PDataBase.cc:523
 PDataBase.cc:524
 PDataBase.cc:525
 PDataBase.cc:526
 PDataBase.cc:527
 PDataBase.cc:528
 PDataBase.cc:529
 PDataBase.cc:530
 PDataBase.cc:531
 PDataBase.cc:532
 PDataBase.cc:533
 PDataBase.cc:534
 PDataBase.cc:535
 PDataBase.cc:536
 PDataBase.cc:537
 PDataBase.cc:538
 PDataBase.cc:539
 PDataBase.cc:540
 PDataBase.cc:541
 PDataBase.cc:542
 PDataBase.cc:543
 PDataBase.cc:544
 PDataBase.cc:545
 PDataBase.cc:546
 PDataBase.cc:547
 PDataBase.cc:548
 PDataBase.cc:549
 PDataBase.cc:550
 PDataBase.cc:551
 PDataBase.cc:552
 PDataBase.cc:553
 PDataBase.cc:554
 PDataBase.cc:555
 PDataBase.cc:556
 PDataBase.cc:557
 PDataBase.cc:558
 PDataBase.cc:559
 PDataBase.cc:560
 PDataBase.cc:561
 PDataBase.cc:562
 PDataBase.cc:563
 PDataBase.cc:564
 PDataBase.cc:565
 PDataBase.cc:566
 PDataBase.cc:567
 PDataBase.cc:568
 PDataBase.cc:569
 PDataBase.cc:570
 PDataBase.cc:571
 PDataBase.cc:572
 PDataBase.cc:573
 PDataBase.cc:574
 PDataBase.cc:575
 PDataBase.cc:576
 PDataBase.cc:577
 PDataBase.cc:578
 PDataBase.cc:579
 PDataBase.cc:580
 PDataBase.cc:581
 PDataBase.cc:582
 PDataBase.cc:583
 PDataBase.cc:584
 PDataBase.cc:585
 PDataBase.cc:586
 PDataBase.cc:587
 PDataBase.cc:588
 PDataBase.cc:589
 PDataBase.cc:590
 PDataBase.cc:591
 PDataBase.cc:592
 PDataBase.cc:593
 PDataBase.cc:594
 PDataBase.cc:595
 PDataBase.cc:596
 PDataBase.cc:597
 PDataBase.cc:598
 PDataBase.cc:599
 PDataBase.cc:600
 PDataBase.cc:601
 PDataBase.cc:602
 PDataBase.cc:603
 PDataBase.cc:604
 PDataBase.cc:605
 PDataBase.cc:606
 PDataBase.cc:607
 PDataBase.cc:608
 PDataBase.cc:609
 PDataBase.cc:610
 PDataBase.cc:611
 PDataBase.cc:612
 PDataBase.cc:613
 PDataBase.cc:614
 PDataBase.cc:615
 PDataBase.cc:616
 PDataBase.cc:617
 PDataBase.cc:618
 PDataBase.cc:619
 PDataBase.cc:620
 PDataBase.cc:621
 PDataBase.cc:622
 PDataBase.cc:623
 PDataBase.cc:624
 PDataBase.cc:625
 PDataBase.cc:626
 PDataBase.cc:627
 PDataBase.cc:628
 PDataBase.cc:629
 PDataBase.cc:630
 PDataBase.cc:631
 PDataBase.cc:632
 PDataBase.cc:633
 PDataBase.cc:634
 PDataBase.cc:635
 PDataBase.cc:636
 PDataBase.cc:637
 PDataBase.cc:638
 PDataBase.cc:639
 PDataBase.cc:640
 PDataBase.cc:641
 PDataBase.cc:642
 PDataBase.cc:643
 PDataBase.cc:644
 PDataBase.cc:645
 PDataBase.cc:646
 PDataBase.cc:647
 PDataBase.cc:648
 PDataBase.cc:649
 PDataBase.cc:650
 PDataBase.cc:651
 PDataBase.cc:652
 PDataBase.cc:653
 PDataBase.cc:654
 PDataBase.cc:655
 PDataBase.cc:656
 PDataBase.cc:657
 PDataBase.cc:658
 PDataBase.cc:659
 PDataBase.cc:660
 PDataBase.cc:661
 PDataBase.cc:662
 PDataBase.cc:663
 PDataBase.cc:664
 PDataBase.cc:665
 PDataBase.cc:666
 PDataBase.cc:667
 PDataBase.cc:668
 PDataBase.cc:669
 PDataBase.cc:670
 PDataBase.cc:671
 PDataBase.cc:672
 PDataBase.cc:673
 PDataBase.cc:674
 PDataBase.cc:675
 PDataBase.cc:676
 PDataBase.cc:677
 PDataBase.cc:678
 PDataBase.cc:679
 PDataBase.cc:680
 PDataBase.cc:681
 PDataBase.cc:682
 PDataBase.cc:683
 PDataBase.cc:684
 PDataBase.cc:685
 PDataBase.cc:686
 PDataBase.cc:687
 PDataBase.cc:688
 PDataBase.cc:689
 PDataBase.cc:690
 PDataBase.cc:691
 PDataBase.cc:692
 PDataBase.cc:693
 PDataBase.cc:694
 PDataBase.cc:695
 PDataBase.cc:696
 PDataBase.cc:697
 PDataBase.cc:698
 PDataBase.cc:699
 PDataBase.cc:700
 PDataBase.cc:701
 PDataBase.cc:702
 PDataBase.cc:703
 PDataBase.cc:704
 PDataBase.cc:705
 PDataBase.cc:706
 PDataBase.cc:707
 PDataBase.cc:708
 PDataBase.cc:709
 PDataBase.cc:710
 PDataBase.cc:711
 PDataBase.cc:712
 PDataBase.cc:713
 PDataBase.cc:714
 PDataBase.cc:715
 PDataBase.cc:716
 PDataBase.cc:717
 PDataBase.cc:718
 PDataBase.cc:719
 PDataBase.cc:720
 PDataBase.cc:721
 PDataBase.cc:722
 PDataBase.cc:723
 PDataBase.cc:724
 PDataBase.cc:725
 PDataBase.cc:726
 PDataBase.cc:727
 PDataBase.cc:728
 PDataBase.cc:729
 PDataBase.cc:730
 PDataBase.cc:731
 PDataBase.cc:732
 PDataBase.cc:733
 PDataBase.cc:734
 PDataBase.cc:735
 PDataBase.cc:736
 PDataBase.cc:737
 PDataBase.cc:738
 PDataBase.cc:739
 PDataBase.cc:740
 PDataBase.cc:741
 PDataBase.cc:742
 PDataBase.cc:743
 PDataBase.cc:744
 PDataBase.cc:745
 PDataBase.cc:746
 PDataBase.cc:747
 PDataBase.cc:748
 PDataBase.cc:749
 PDataBase.cc:750
 PDataBase.cc:751
 PDataBase.cc:752
 PDataBase.cc:753
 PDataBase.cc:754
 PDataBase.cc:755
 PDataBase.cc:756
 PDataBase.cc:757
 PDataBase.cc:758
 PDataBase.cc:759
 PDataBase.cc:760
 PDataBase.cc:761
 PDataBase.cc:762
 PDataBase.cc:763
 PDataBase.cc:764
 PDataBase.cc:765
 PDataBase.cc:766
 PDataBase.cc:767
 PDataBase.cc:768
 PDataBase.cc:769
 PDataBase.cc:770
 PDataBase.cc:771
 PDataBase.cc:772
 PDataBase.cc:773
 PDataBase.cc:774
 PDataBase.cc:775
 PDataBase.cc:776
 PDataBase.cc:777
 PDataBase.cc:778
 PDataBase.cc:779
 PDataBase.cc:780
 PDataBase.cc:781
 PDataBase.cc:782
 PDataBase.cc:783
 PDataBase.cc:784
 PDataBase.cc:785
 PDataBase.cc:786
 PDataBase.cc:787
 PDataBase.cc:788
 PDataBase.cc:789
 PDataBase.cc:790
 PDataBase.cc:791
 PDataBase.cc:792
 PDataBase.cc:793
 PDataBase.cc:794
 PDataBase.cc:795
 PDataBase.cc:796
 PDataBase.cc:797
 PDataBase.cc:798
 PDataBase.cc:799
 PDataBase.cc:800
 PDataBase.cc:801
 PDataBase.cc:802
 PDataBase.cc:803
 PDataBase.cc:804
 PDataBase.cc:805
 PDataBase.cc:806
 PDataBase.cc:807
 PDataBase.cc:808
 PDataBase.cc:809
 PDataBase.cc:810
 PDataBase.cc:811
 PDataBase.cc:812
 PDataBase.cc:813
 PDataBase.cc:814
 PDataBase.cc:815
 PDataBase.cc:816
 PDataBase.cc:817
 PDataBase.cc:818
 PDataBase.cc:819
 PDataBase.cc:820
 PDataBase.cc:821
 PDataBase.cc:822
 PDataBase.cc:823
 PDataBase.cc:824
 PDataBase.cc:825
 PDataBase.cc:826
 PDataBase.cc:827
 PDataBase.cc:828
 PDataBase.cc:829
 PDataBase.cc:830
 PDataBase.cc:831
 PDataBase.cc:832
 PDataBase.cc:833
 PDataBase.cc:834
 PDataBase.cc:835
 PDataBase.cc:836
 PDataBase.cc:837
 PDataBase.cc:838
 PDataBase.cc:839
 PDataBase.cc:840
 PDataBase.cc:841
 PDataBase.cc:842
 PDataBase.cc:843
 PDataBase.cc:844
 PDataBase.cc:845
 PDataBase.cc:846
 PDataBase.cc:847
 PDataBase.cc:848
 PDataBase.cc:849
 PDataBase.cc:850
 PDataBase.cc:851
 PDataBase.cc:852