// $Id: BrGeantInput.cxx,v 1.14 1998/08/14 21:25:14 videbaek Exp $
//
// $Log: BrGeantInput.cxx,v $
// Revision 1.14 1998/08/14 21:25:14 videbaek
// changed include files for unix
//
// Revision 1.13 1998/07/31 19:32:42 videbaek
// Check and set error on read problems
//
// Revision 1.12 1998/07/20 17:42:58 videbaek
// Added Pid hit to hit structure. Needed for effecient handling
// of detector response.
//
// Revision 1.11 1998/07/17 02:20:08 hagel
// Modifications for byte swapping in BrGeantInput
//
// Revision 1.10 1998/06/23 20:22:28 hagel
// Zero elements of many (not all) objects to avoid problems with overlaying in memory
//
// Revision 1.9 1998/06/21 20:11:05 hagel
// cleanup
//
// Revision 1.8 1998/05/14 21:18:50 videbaek
// update makefile - do not reload .so libraries
//
// Revision 1.7 1998/04/30 22:30:00 hagel
// Fix errors in WIN32 stuff again
//
// Revision 1.6 1998/04/30 17:12:35 videbaek
// Added functionality to BrGeantInput
//
// Revision 1.3 1998/04/08 18:09:24 videbaek
// changed GeantInput class to use open,read
//
// Revision 1.2 1998/04/06 21:12:11 videbaek
// Clean up and additions for Win95
//
// Revision 1.1 1998/04/03 21:15:04 videbaek
// part of first base release
//
//
// April 21 : fStatus was not set properly following i/o actions.
// This was the reason the TestBase.C failed for a non existing file
// Note that the code has also been changed for Linux,
// ensure updates are merged.
//
// April 24/25 Add handling of the protected variables (from BrIOModule) fError and FEof
// to ensure uniform handling of errors, and end-of-data across different
// BrIOModules.
//
// July 8 Increase size of GeantHits to include Pid of hit
//
#include <iostream.h>
#include <fcntl.h>
#include <math.h>
#ifndef WIN32
# include <unistd.h>
#else
# include <sys/stat.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <sys/types.h>
#endif
#include "BrGeantInput.h"
#include "BrDataTable.h"
#include "BrGeantHit.h"
#include "BrGeantTrack.h"
#include "BrEvent.h"
ClassImp(BrGeantInput)
const int END_OF_STREAM_EVENT = -1;
const int EVENT_STREAM_HEADER = 1;
const int EVENT_STREAM_HIT = 2;
const int EVENT_STREAM_TRACK = 3;
////////////////////////////////////////////////////////////////
// //
// BrGeantInput provides an interface to GBRAHMS output //
//
// The class is derived from the general input/output class
// and falls natural into the hierachi of module classes,
// which the BrGeantData does not.
// In terms of functionality it is very similar
//
////////////////////////////////////////////////////////////////
//#define debug
//#define BR_DEBUG
BrGeantInput::BrGeantInput()
{
//
// Constructor. Set fFilePointer and fEventCounter to NULL
// In root environment use the named constructor normally.
#ifdef _BRDEBUG
cout << "Ctor : BrGeantInput " << endl;
#endif
#if USE_FSTREAM
fFilePointer = NULL;
#else
fFileDescriptor = -1;
#endif
fEventCounter = 0;
rHeader = kFALSE;
fByteSwap = kFALSE;
}
BrGeantInput::BrGeantInput(Char_t *Name) :
BrIOModule(Name, Name)
{
//
// Constructor. Set fFilePointer and fEventCounter to NULL
// name becomes Name and Title for the Module.
// No data file is opened this has to be done in
// the Open() method.
//
#if USE_FSTREAM
fFilePointer = NULL;
#else
fFileDescriptor = -1;
#endif
fEventCounter = 0;
rHeader = kFALSE;
}
BrGeantInput::~BrGeantInput(){
//
// Destructor for BrGeantInput. Close the file if open.
//
#if USE_FSTREAM
if(fFilePointer) {
fFilePointer->close();
delete fFilePointer;
}
#else
if(fFileDescriptor != -1)
close(fFileDescriptor);
#endif
}
Bool_t BrGeantInput::Open(Char_t *fname)
{
// Open the C stream file with fname. Returns kFALSE
// if the file can't be opened.
// Otherwise the fFileName data member is set to the
// corresponding filepointer. The file header is read
// and the volume information is stored in the intrinsic arrays
//
fStatus = 0;
if(!fname)
{
printf("Can't open file : %sn", fname);
return kFALSE;
}
sprintf(fFileName,"%s",fname);
#if USE_FSTREAM
if(!fFilePointer)
fFilePointer = new ifstream();
if(!fFilePointer) {
printf("Can't create fFilePointer object %s\n",fFileName);
return kFALSE;
}
fFilePointer->open(fFileName,ios::binary|ios::in);
if(fFilePointer->fail()) {
printf("Can't open File %s\n",fFileName);
delete fFilePointer;
fFilePointer = NULL;
fError = kTRUE;
return kFALSE;
}
else {
fStatus = 1;
fError = kFALSE;
fEof = kFALSE;
return ReadStreamHeader();
fBytesTransferred =0;
}
#else
#ifndef WIN32
fFileDescriptor = open(fFileName, O_RDONLY);
#else
fFileDescriptor = open(fFileName, O_RDONLY|O_BINARY);
#endif
if(fFileDescriptor == -1 ) {
printf("Can't open File %s\n",fFileName);
fError = kTRUE;
return kFALSE;
}
else {
fStatus = 1;
fBytesTransferred =0;
return ReadStreamHeader();
}
#endif
}
Bool_t BrGeantInput::Close()
{
// Close the file Opened by the object. Return
// kFALSE if no file was open.
#if USE_FSTREAM
if(fFilePointer)
{
fFilePointer->close();
delete fFilePointer;
fFilePointer = NULL;
return kTRUE;
}
else
{
return kFALSE;
}
#else
if(fFileDescriptor != -1){
close(fFileDescriptor);
fFileDescriptor = -1;
}
return kTRUE;
#endif
}
Bool_t BrGeantInput::ReadStreamHeader()
{
//
// read the volume information from the header.
// At this time it is only used to define the Names
// of the hit structures. The information is not used by other parts
// of the reconstruction even though one could imagine that
// the code could 'inquire' on volume information for a specific
// detector.
// This is not implemented. A better way will alos be to have a general
// method for passing geometries around.
//
Int_t i, ivol;
Int_t nb = 4; Int_t nread;
Char_t* VolumeName;
Char_t * numvol = (Char_t *) (&fNumberOfVolumes);
#if USE_FSTREAM
fFilePointer->read(numvol,nb);
#else
nread = read(fFileDescriptor, numvol, nb);
if(nb != nread){
if(nb == 0) fEof = kTRUE;
if(nb == -1) fError = kTRUE;
return kFALSE;
}
#endif
fBytesTransferred +=nb;
/* if(fNumberOfVolumes > MAXGIVOLU){
cout << "Try to convert file first " << endl;
return kFALSE;
};*/
if(fNumberOfVolumes > MAXGIVOLU){
fByteSwap = kTRUE;
SwapLong(&fNumberOfVolumes,4);
};
for(ivol=0; ivol<fNumberOfVolumes; ivol++) {
Char_t *bufp = (Char_t*) (&fVolume[ivol]);
nb = sizeof(GeantVol);
#if USE_FSTREAM
fFilePointer->read(bufp, nb);
#else
nread = read(fFileDescriptor, bufp, nb);
if(nb != nread){
if(nb == 0) fEof = kTRUE;
if(nb == -1) fError = kTRUE;
return kFALSE;
}
#endif
if(fByteSwap) {
SwapLong((int*)&fVolume[ivol].shape,8);
SwapLong((int*)&fVolume[ivol].pos[0],96);
}
fBytesTransferred +=nb;
VolumeName = fVolume[ivol].Name;
VolumeName[sizeof(fVolume[ivol].Name)] = 0;
// VolumeName[sizeof(fVolume[ivol].Name)] = 0;
//need to do this because fortran(geant?) pads with blank (32)
for(i=0;i<sizeof(fVolume[ivol].Name);i++) {
if(fVolume[ivol].Name[i] == 32) fVolume[ivol].Name[i] = 0;
}
}
SetrHeader( kTRUE );
return kTRUE;
}
void BrGeantInput::SkipEvent(Int_t numevt)
{
BrEvent *dummyevent;
for(Int_t i=0;i<numevt;i++) {
dummyevent = new BrEvent("Dummy",0,0);
Event(dummyevent);
delete dummyevent;
}
}
void BrGeantInput::Event(BrEvent* event)
{
// Reads one event from the C-stream data file.The BrEvent
// object has hitlist and tracklist added to the Event.
//
// This object is filled with data read from the file.
// It is the responsibility of the calling program to have created the
// event.
//
// Releasing the memory for this event is the responsibility
// of the function/macro calling Event();
Int_t rectyp=0, nb, ivol, nread;
Char_t* bufp;
Int_t EventHeader[2];
Char_t name[64];
GeantStreamHits fHits;
GeantStreamTracks fTracks;
BrDataTable *HitBuffer[30];
//
//
// Create new data container for Geant Tracks and
// Geant Hits (for each of the possible volumes
//
BrDataTable *TrackBuffer = new BrDataTable("GeantTracks");
for(ivol=0;ivol<fNumberOfVolumes;ivol++) {
if(fVolume[ivol].Active == 1 ){
sprintf(name,"GeantHits %sx0",fVolume[ivol].Name);
HitBuffer[ivol] = new BrDataTable(name);
event->AddObject(HitBuffer[ivol]);
}
}
event->AddObject(TrackBuffer);
event->GetEventHeader()->SetRunNumber(0);
event->GetEventHeader()->SetEventNumber(fEventCounter);
//
fStatus = 1;
fEof = kFALSE;
fError = kFALSE;
while(rectyp != END_OF_STREAM_EVENT) {
nb = 4;
bufp = (char*) &rectyp;
#if USE_FSTREAM
fFilePointer->read(bufp, nb);
if(fFilePointer->eof()) {
cout<<"End of STREAM file found: closing file"<<endl;
fFilePointer->close();
fFilePointer = NULL;
fEof = kTRUE;
fStatus = 0;
return;
}
if(fFilePointer->bad()) {
cout << "Unexpected Bad file\n";
fStatus = 0;
fError = kTRUE;
#ifdef debug
cout << nread << " " << fStatus << endl;
if(fEof)
cout << "* EOF : TRUE \n";
else
cout << "* EOF : FALSE \n";
if(fError)
cout << "* ERROR : TRUE \n";
else
cout << "* ERROR : FALSE \n";
#endif
return;
}
#else
nread = read(fFileDescriptor, bufp, nb);
if(nb != nread){
if(nread == 0) fEof = kTRUE;
if(nread < 0 ) fError = kTRUE;
fStatus = 0;
#ifdef debug
cout << nread << " " << fStatus << endl;
if(fEof)
cout << "* EOF : TRUE \n";
else
cout << "* EOF : FALSE \n";
if(fError)
cout << "* ERROR : TRUE \n";
else
cout << "* ERROR : FALSE \n";
#endif
return;
}
#endif
if(fByteSwap) SwapLong(&rectyp,nb);
fBytesTransferred +=nb;
switch (rectyp) {
case END_OF_STREAM_EVENT:
break;
case EVENT_STREAM_HEADER:
nb = sizeof(EventHeader);
bufp = (char*) EventHeader;
#if USE_FSTREAM
fFilePointer->read(bufp,nb);
#else
nread = read(fFileDescriptor, bufp, nb);
if(nb != nread){
if(nread == 0) fEof = kTRUE;
if(nread < 0) fError = kTRUE;
fStatus = 0;
#ifdef debug
cout << nread << " " << fStatus << endl;
if(fEof)
cout << "* EOF : TRUE \n";
else
cout << "* EOF : FALSE \n";
if(fError)
cout << "* ERROR : TRUE \n";
else
cout << "* ERROR : FALSE \n";
#endif
return;
}
#endif
if(fByteSwap) SwapLong((int*)EventHeader,nb);
fBytesTransferred +=nb;
event->GetEventHeader()->SetEventNumber(EventHeader[0]);
break;
case EVENT_STREAM_TRACK:
nb = sizeof(GeantStreamTracks);
bufp = (char*) &fTracks;
#if USE_FSTREAM
fFilePointer->read(bufp,nb);
if(fFilePointer->bad()) {
cerr<<"Bad status"<<endl;
fStatus = 0;
return;
}
if(fFilePointer->eof()) {
cerr<<"EOF status"<<endl;
fStatus = 0;
return;
}
if(fFilePointer->fail()) {
cerr<<"Fail status"<<endl;
fStatus = 0;
return;
}
#else
nread = read(fFileDescriptor, bufp, nb);
if(nb != nread){
if(nread == 0) fEof = kTRUE;
if(nread < 0 ) fError = kTRUE;
fStatus = 0;
#ifdef debug
cout << nread << " " << fStatus << endl;
cout << fStatus << endl;
if(fEof)
cout << "* EOF : TRUE \n";
else
cout << "* EOF : FALSE \n";
if(fError)
cout << "* ERROR : TRUE \n";
else
cout << "* ERROR : FALSE \n";
#endif
return;
}
#endif
if(fByteSwap) SwapLong((int*)bufp,44);
fBytesTransferred +=nb;
TrackBuffer->Add(new BrGeantTrack(fTracks));
break;
case EVENT_STREAM_HIT:
nb = sizeof(GeantStreamHits);
bufp = (char*) & fHits;
#if USE_FSTREAM
fFilePointer->read(bufp,nb);
if(fFilePointer->bad()) {
cerr<<"Bad status"<<endl;
fStatus = 0;
return;
}
if(fFilePointer->eof()) {
cerr<<"EOF status"<<endl;
fStatus = 0;
return;
}
if(fFilePointer->fail()) {
cerr<<"Fail status"<<endl;
fStatus = 0;
#ifdef debug
cout << fStatus << endl;
if(fEof)
cout << "* EOF : TRUE \n";
else
cout << "* EOF : FALSE \n";
if(fError)
cout << "* ERROR : TRUE \n";
else
cout << "* ERROR : FALSE \n";
#endif
return;
}
#else
nread = read(fFileDescriptor, bufp, nb);
if(nb != nread){
if(nread == 0) fEof = kTRUE;
if(nread < 0 ) fError = kTRUE;
fStatus = 0;
#ifdef debug
cout << nread << " " << fStatus << endl;
if(fEof)
cout << "* EOF : TRUE \n";
else
cout << "* EOF : FALSE \n";
if(fError)
cout << "* ERROR : TRUE \n";
else
cout << "* ERROR : FALSE \n";
#endif
return;
}
#endif
if(fByteSwap) SwapLong((int*)bufp,nb);
fBytesTransferred +=nb;
ivol = fHits.DetectorId - 1; //-1 needed because indices start at 0
if( fHits.dedx > 0 ) {
HitBuffer[ivol]->Add(new BrGeantHit(fHits));
}
break;
default:
// This should not happen!!
// Indicates logic error.
fStatus = 0;
fError = kTRUE;
cout <<"*** Problem in data:" << endl;
cout << "rectype in stream file is " << rectyp<< endl;
#ifdef debug
cout << fStatus << endl;
if(fEof)
cout << "* EOF : TRUE \n";
else
cout << "* EOF : FALSE \n";
if(fError)
cout << "* ERROR : TRUE \n";
else
cout << "* ERROR : FALSE \n";
#endif
return;
}
}
sprintf(name,"event_%d_%d",event->GetRunNumber(),event->GetEventNumber());
event->SetName(name);
sprintf(name,"BrEvent %d %d",event->GetRunNumber(),event->GetEventNumber());
event->SetTitle(name);
fEventCounter++;
#ifdef debug
cout << fStatus << endl;
if(fEof)
cout << "* EOF : TRUE \n";
else
cout << "* EOF : FALSE \n";
if(fError)
cout << "* ERROR : TRUE \n";
else
cout << "* ERROR : FALSE \n";
#endif
return;
}
void BrGeantInput::SwapLong(int *buffer,int nb)
{
int i,j;
union {
int il;
char ib[4];
} temp;
union {
int il;
char ib[4];
} temp1;
j = 0;
for(i=0;i<nb;i+=4) {
temp.il = buffer[j];
temp1.ib[0] = temp.ib[3];
temp1.ib[1] = temp.ib[2];
temp1.ib[2] = temp.ib[1];
temp1.ib[3] = temp.ib[0];
buffer[j] = temp1.il;
j++;
}
}
ROOT page - Class index - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.