Re: your mail

Alexander Zvyagin (zvyagin_at_mx.ihep.su)
Mon, 30 Nov 1998 14:13:18 GMT+03:00


Date: Mon, 30 Nov 1998 14:13:16 +0000
From: Alexander Zvyagin <ZVYAGIN_at_mx.ihep.su>
X-Sender: ZVYAGIN@polar.ihep.su
To: Canguo Li <licg@hpws7.ihep.ac.cn>
cc: talk root <roottalk@hpsalo.cern.ch>
Subject: Re: your mail
Message-ID: <Pine.VMS.3.91-b11-vms.981130141214.13632A-100000@polar.ihep.su>
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII

Dear Canguo,

> Can ROOT read card files (like FFREAD)?
> I guess the answer should be yes. Can anybody refer me to the relevant
> section of the ROOT manuals?
> My plan is to read in things like detector parameters from
> free-formatted files into arrays in my ROOT application, and then in my
> program assign these parameters to some objects(e.g., material class
> predefined by ROOT). I think this should work. However, I wonder if there's
> a better or more efficient way to achieve this purpose.

Below is the example of ROOT class with function that produce FFREAD keys.
Notes:
1. All FFREAD keys must be data members of a ROOT class.
2. Data memebers of class Parameter may be
Float_t (for REAL) or (U)Int_t (for INTEGER).
3. One-dimension arrays are supported.
4. The first symbol of data memeber name will removed. (Removing leading
'f','g' or 'k' symbols.)

------------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////////

// Example of GEANT UGINIT subroutine.

const int FFREAD_SIZE=2000;
float cfread_[FFREAD_SIZE];

void UGINIT(void)
{
GINIT();

FFINIT(FFREAD_SIZE);
FFSET("SIZE",32);
Parameters P;
P.CreateFFREADcards();
GFFGO();
P.Dump();

//....
}

//////////////////////////////////////////////////////////////////////////////

class Parameters : public TObject
{
public:

void CreateFFREADcards (void);
virtual ~Parameters (void) {}
Parameters (void) :// For default values.
fPar (0.01)
{ fDim[0]=0; fDim[1]=1;}

Float_t fPar; // Par Set your name!
Int_t fDim[2]; // Dim Set your name!

private:

ClassDef(Parameters,1) // Parameters
};

//////////////////////////////////////////////////////////////////////////////

void ffkey_( const char *key, void *ptr, const int &Nvar, const char *type,
int,int);
inline void FFKEY(const char *key, void *ptr, int Nvar, const char *type)
{ ffkey_(key,ptr,Nvar,type,strlen(key),strlen(type)); }

void
Parameters::CreateFFREADcards(void)
{
cout << __PRETTY_FUNCTION__ << "\n";

TIter next(Class()->GetListOfDataMembers());

while( TDataMember *obj = (TDataMember*)next() )
{
if( !strcmp("fgIsA",obj->GetName()) ) // Skip this variable
continue;

// cout << obj -> GetName() << "\n"
// << obj -> GetDataType() -> GetTypeName() << "\n"
// << obj -> GetDataType() -> GetFullTypeName() << "\n"
// << obj -> GetOffset() << "\n"
// << obj -> GetArrayDim() << "\n"
// << obj -> GetMaxIndex(0) << "\n"
// << "-----------------------------------------------\n";

cout << obj->GetName(); // Print variable name
for( int i=strlen(obj->GetName()); i<22; i++ ) // Add spaces for good
cout << ' '; // print.

cout << obj->GetDataType()->GetFullTypeName(); // Print variable type
for( int i=strlen(obj->GetDataType()->GetFullTypeName()); i<18; i++ )
cout << ' '; // Add spaces for good print

if( strlen(obj->GetName())<2 || obj->GetName()[0]!='f' )
{
cout << "Bad name. Skipped.\n";
continue;
}

char type[11]="";

if( !strcmp("int" , obj -> GetDataType() -> GetTypeName()) )
strcpy(type,"INTEGER");

if( !strcmp("float" , obj -> GetDataType() -> GetTypeName()) )
strcpy(type,"REAL");

if( *type == 0 )
{
cout << "Unknown type.\n";
continue;
}

int size;
switch( obj->GetArrayDim() )
{
case 0: size = 1; break;
case 1: size = obj->GetMaxIndex(0); break;
default:
cout << "Only one dimensional arrays are supported. Skipped.\n";
continue;
}

cout.form("amount=%d\n",size);

FFKEY( obj->GetName()+1 , (void*)((int)this + (int)obj->GetOffset()) ,
size , type );
}
}

//////////////////////////////////////////////////////////////////////////////