memory crash (revisited)

Piergiorgio Cerello (cerello@to.infn.it)
Tue, 25 Aug 1998 11:47:33 +0200 (MET DST)


Dear Rooters,

I'm running the analysis of a set of data and I get a memory crash after some
thousands of events. The problem seems to be related to the destructors, but
there are strange behaviours that I don't understand (that's why I ask for
help...).

The code runs under OSF and Linux, showing the same behaviour.

1) I have a first stage in which I build for every event, among other objects,
a TObjArray of hits, described by the Class TFndHLmd.
This part is run in background by a program (geb2hdt.C) which was
successfully tested up to more than 50000 events with 200 hits each, and
doesn't give any memory problem.

2) In the second stage, I try to analyze the TObjArrays with root, and there
comes the memory crash, after about 4000 events, corresponding to about
800000 hits.

Of course, I scanned all my constructors/destructors, but I couldn't find the
cause of the crash.
Moreover, I don't understand why the problem comes only with the interactive
session, since the constructors/destructors are the same.

In the following, you can find the interactive macro (lmd_adc.C, 2nd stage),
the geb2hdt.C program (1st stage) and the code for the involved class
(TFndHLmd.h and TFndHLmd.C)

Thanks in advance for any help,

Piergiorgio

1. lmd_adc.C

{

gROOT->Reset();

printf("Start lmd_adc.C Macro\n");
const Int_t kUPDATE = 50;
const Int_t kCHECK = 100;
const Int_t ndch = 16;

TFile *p;
TFile *f;

TTree *ftree;
TObjArray *fHLmd=0;
Int_t fNHLmd=0;
TBranch *bhlmd;
TBranch *bnlmd;

TFndHLmd *hlmd;

f1 = new TCanvas("f1","Finuda Monitor",10,10,800,800);

TH2F *lmdmapadc = new TH2F("lmdmapadc","adc lmd map",20,10.5,30.5,24,0.5,24.5);
TH2F *lmdmapadc0 = new TH2F("lmdmapadc0","adc != 0 lmd map",20,10.5,30.5,24,0.5,24.5);
TH2F *lmdmapadc00 = new TH2F("lmdmapadc00","adc L,R != 0 lmd map",20,10.5,30.5,24,0.5,24.5);
TH2F *lmdmapadcl = new TH2F("lmdmapadcl","adcl lmd map",20,10.5,30.5,24,0.5,24.5);
TH2F *lmdmapadcr = new TH2F("lmdmapadcr","adcr lmd map",20,10.5,30.5,24,0.5,24.5);

TH1F *lmdadcl[ndch];
TH1F *lmdadcr[ndch];
TH1F *lmdcrg[ndch];
TH2F *lmdadc[ndch];

Int_t sf;
Int_t idx = 0;
for(sf=0; sf<ndch; sf++){
char sfc[3];
idx = sf+11;
if(sf>=ndch/2) idx = sf+13;
sprintf(sfc,"%d",idx);

// HISTOGRAMS CREATION

char hname1[8];
hname1[0] = 'l';
hname1[1] = 'm';
hname1[2] = 'd';
hname1[3] = 'a';
hname1[4] = 'd';
hname1[5] = 'c';
hname1[6] = 'l';
hname1[7] = '\0';
char hname2[8];
hname2[0] = 'l';
hname2[1] = 'm';
hname2[2] = 'd';
hname2[3] = 'a';
hname2[4] = 'd';
hname2[5] = 'c';
hname2[6] = 'r';
hname2[7] = '\0';
char hname3[7];
hname3[0] = 'l';
hname3[1] = 'm';
hname3[2] = 'd';
hname3[3] = 'a';
hname3[4] = 'd';
hname3[5] = 'c';
hname3[6] = '\0';

char hname4[7];
hname4[0] = 'l';
hname4[1] = 'm';
hname4[2] = 'd';
hname4[3] = 'c';
hname4[4] = 'r';
hname4[5] = 'g';
hname4[6] = '\0';

char *hhname = strcat(hname1,sfc);
printf("hhname %s\n",hhname);
lmdadcl[sf] = new TH1F(hhname,"adcl",205,0,4100);
char *hhname = strcat(hname2,sfc);
printf("hhname %s\n",hhname);
lmdadcr[sf] = new TH1F(hhname,"adcr",205,0,4100);
char *hhname = strcat(hname3,sfc);
printf("hhname %s\n",hhname);
lmdadc[sf] = new TH2F(hhname,"adcl vs adcr",205,0,4100,205,0,4100);
char *hhname = strcat(hname4,sfc);
printf("hhname %s\n",hhname);
lmdcrg[sf] = new TH1F(hhname,"charge",410,0,8200);

lmdadcl[sf]->SetFillColor(6);
lmdadcr[sf]->SetFillColor(7);
lmdadc[sf]->SetFillColor(8);
lmdcrg[sf]->SetFillColor(9);
}

char *fpth;
printf("Path to the main data directory ?\n");
scanf("%s",&fpth);

Int_t nsum = 1;
while(nsum != 0) {

// OPEN INPUT FILE
printf("open the ROOT input file\n");

char *nrun;
char *FVMS;

printf("Run type ?\n");
scanf("%s",&FVMS);
printf("Run number (5 digits)? \n");
scanf("%s",&nrun);

const char *fdir = "/HDT/";
const char *sufx = ".hdt";
Char_t *fRAW = new Char_t[strlen(&fpth)+strlen(fdir)+strlen(&FVMS)+strlen(sufx)+strlen(&nrun)];
strcpy(fRAW,&fpth);
fRAW = strcat(fRAW,fdir);
fRAW = strcat(fRAW,&FVMS);
fRAW = strcat(fRAW,&nrun);
fRAW = strcat(fRAW,sufx);
printf("%s file\n",fRAW);
f = new TFile(fRAW);

ftree = (TTree*)f->Get("F");

bnlmd = ftree->GetBranch("fNHLmd");
bhlmd = ftree->GetBranch("fHLmd");
Int_t nbr = ftree->GetNbranches();
printf("HDT Tree with %d branches ",nbr);

bnlmd->SetAddress(&fNHLmd);
bhlmd->SetAddress(&fHLmd);

Int_t nevent = (Int_t)bnlmd->GetEntries();
printf("and %d events \n",nevent);

Int_t goon;
Int_t firstevt=0;
Int_t lastevt=0;

printf("Type initial event number\n");
scanf("%d",&firstevt);
if(firstevt<=0) {
firstevt = 0;
printf("WARNING: firstevt FORCED to 0\n");
}

printf("Type final event number\n");
scanf("%d",&lastevt);
if(lastevt>=nevent) {
lastevt = nevent-1;
printf("WARNING: lastevt FORCED to (nevent-1)\n");
}

if(lastevt<firstevt)
printf("WARNING: lastevt SMALLER than firstevt\n");

if(firstevt>=0 || firstevt<lastevt && lastevt<nevent) {
for (Int_t i=firstevt;i<lastevt;i++) {

fHLmd = new TObjArray();
bhlmd->GetEvent(i);
bnlmd->GetEvent(i);

if(!(i%kCHECK))printf("Event %d, %d lmd hits\n",i,fNHLmd);

// FILL HISTOGRAMS
for (Int_t j=0; j<fNHLmd; j++) {
hlmd = (TFndHLmd*) fHLmd->At(j);
Int_t dch = hlmd->GetCham();
Int_t wire = hlmd->GetWire();
Int_t sf=0;
if(dch <= 18 && dch >= 11)
sf = dch - 11;
if(dch <= 28 && dch >=21)
sf = dch - 13;
lmdmapadc->Fill((Float_t) dch,(Float_t) wire);
Int_t al = hlmd->GetAdcL();
Int_t ar = hlmd->GetAdcR();

if((al+ar)!= 0)
lmdmapadc0->Fill((Float_t) dch,(Float_t) wire);
if((al*ar) != 0)
lmdmapadc00->Fill((Float_t) dch,(Float_t) wire);
if(al != 0)
lmdmapadcl->Fill((Float_t) dch,(Float_t) wire);
if(ar != 0)
lmdmapadcr->Fill((Float_t) dch,(Float_t) wire);

lmdadcl[sf]->Fill(al);
lmdadcr[sf]->Fill(ar);
lmdadc[sf]->Fill(ar,al);
lmdcrg[sf]->Fill(al+ar);
}

fHLmd->Delete();
delete fHLmd;

}
}
printf("new run? "1" yes, "0" no\n");
scanf("%d",&nsum);
}

// OPEN Histogram FILE
const char *SUFF = "_lmd_adc.hist";
Char_t *fhist = new Char_t[strlen(&FVMS)+strlen(&nrun)+strlen(SUFF)];
strcpy(fhist,&FVMS);
fhist = strcat(fhist,&nrun);
fhist = strcat(fhist,SUFF);
printf("write file %s\n",fhist);
TFile *fist = new TFile(fhist,"RECREATE","Finuda ROOT histograms");
lmdmapadc->Write();
lmdmapadcl->Write();
lmdmapadcr->Write();
lmdmapadc0->Write();
lmdmapadc00->Write();
for(Int_t sf = 0; sf < ndch; sf++){
lmdadcl[sf]->Write();
lmdadcr[sf]->Write();
lmdcrg[sf]->Write();
lmdadc[sf]->Write();
}
fist->Close();

}

2. geb2hdt.C

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <iostream.h>

//******************************************************************/
//* ROOT include files */
//******************************************************************/

#include "TROOT.h"
#include "TFile.h"
#include "TH1.h"
#include "TH2.h"
#include "TProfile.h"
#include "TNtuple.h"
#include "TRandom.h"
#include "TTree.h"
#include "TBranch.h"
#include "TObjArray.h"
#include "TDirectory.h"
#include "TServerSocket.h"
#include "TSocket.h"
#include "TMessage.h"
#include "TBuffer.h"

//******************************************************************/
//* FINUDA include files */
//******************************************************************/

#include "TFndFeeMap.h"
#include "TFndConst.h"
#include "TFndHHdr.h"
#include "TFndRawEqp.h"
#include "TFndRawSil.h"
#include "TFndRdt.h"
#include "TFndHdt.h"
#include "TFndHSil.h"
#include "TFndHTof.h"
#include "TFndHLmd.h"
#include "TFndHStb.h"
#include "TFndTrig.h"
#include "TFndCorbo.h"
#include "TFndDate.h"
#include "TFndGenInfo.h"

//******************************************************************/
//*-------> UNIX only */
//******************************************************************/

#include <fcntl.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/types.h>

#include <sys/socket.h>
#include <sys/un.h>

#include <netinet/in.h>
#include <netdb.h>

//******************************************************************/
//*-------> ZEBRA Common Block */
//******************************************************************/

#include "cfortran.h"
#include "TFndZebini.h"

ZEBINI_DEF Zebini;

#ifdef __SC__
long G__globalvarpointer;
#endif

TROOT geb2hdt("geb2hdt","FINUDA geb2hdt conversion");

//******************************************************************/
//* main */
//******************************************************************/

main(Int_t argc, Char_t **argv) {

//******************************************************************/
//* Read the mSQL database */
//******************************************************************/

// char *host = argv[1];
// cout << "mSQL host is " << host << endl;

const Int_t EVHEAD=0x10;
const Int_t N_DET = 6;

// build up input file name

const char *fpth = argv[2];
const char *fgeb = "/geb/";
const char *fnam = argv[3];
const char *fonl = "onl";
const char *fraw = ".raw";

Int_t onlflg = 0;
printf("argv[3] %s\n",fnam);
cout << fnam << endl;
if(!strcmp(fnam,fonl)) onlflg = 1;
//cout << "Online flag is " << onlflg << endl;

Int_t kSCALE = 1;
if(onlflg) kSCALE = 10;

Int_t ilen = strlen(fpth)+strlen(fgeb)+strlen(fnam)+strlen(fraw);
Char_t *ifn = new Char_t[ilen];
strcpy(ifn,fpth);
ifn = strcat(ifn,fgeb);
ifn = strcat(ifn,fnam);
ifn = strcat(ifn,fraw);

// open input file
FILE *f;
if(!onlflg) {
f = fopen(ifn,"rb");
if (f==NULL) {
cout << "file " << ifn << " does not exist" << endl;
exit(0);
}
}
// build up output file name

const char *frdt = "/HDT/";
const char *frot = ".hdt";
Int_t olen = strlen(fpth)+strlen(frdt)+strlen(fnam)+strlen(frot);
Char_t *ofn = new Char_t[olen];
strcpy(ofn,fpth);
ofn = strcat(ofn,frdt);
ofn = strcat(ofn,fnam);
ofn = strcat(ofn,frot);

Int_t fSockId = 0;
Int_t rawsize = 0;
Int_t ierr = 0;

if (onlflg) {

Int_t port_ev = 1242;
struct sockaddr_in myaddr;
bzero((char *) &myaddr, sizeof(struct sockaddr_in));
myaddr.sin_family = AF_INET;
myaddr.sin_addr.s_addr = INADDR_ANY;
myaddr.sin_port = htons(port_ev);
fSockId = socket(AF_INET, SOCK_DGRAM, 0);
cout << " fSockId = " << fSockId << endl;
if(fSockId == -1) {
ierr = -1;
cout << "ierr from FndRun(socket) is " << ierr << endl;
}
rawsize = 32000;
setsockopt(fSockId,SOL_SOCKET,SO_RCVBUF,(char *) &rawsize,sizeof(rawsize));
ierr = bind(fSockId, (sockaddr *) &myaddr, sizeof(struct sockaddr_in));
if(ierr == -1) {
ierr = -2;
cout << "ierr from FndRun(socket) is " << ierr << endl;
}

rawsize /= 4;
}
if(!onlflg) {
// read "event 0" header
UInt_t *raw = new UInt_t[EVHEAD];
if (fread(raw,sizeof(UInt_t), EVHEAD,f) !=EVHEAD) {
cout << "file " << ifn << " is shorter than event header" << endl;
exit(0);
}
rewind(f);

// swap "event 0" header if needed
for (Int_t j = 0; j< EVHEAD;j++ ) raw[j] = host2net(raw[j]);
delete [] raw;
}

// create RDT & HDT output file and Tree

cout << "Create Trees" << endl;
TFile *of = new TFile(ofn,"RECREATE","Finuda ROOT histograms");
TTree *rdtt = new TTree("RawTree", "FINUDA raw event tree");
TTree *hdtt = new TTree("F","FINUDA HDT tree");
hdtt->SetAutoSave(10000000); // autosave when 10 Mbytes written
rdtt->SetAutoSave(10000000); // autosave when 10 Mbytes written

cout << "Create RDT" << endl;
TFndRdt *fndrdt = new TFndRdt();
TFndHdt *fndhdt = new TFndHdt();

TFndGenInfo *g = new TFndGenInfo();

cout << "Create branches " << endl;

TBranch *Bhdr;
TBranch *Bdet[N_DET];
TFndHHdr *hdr = 0;
TFndRawEqp *gts = 0;
TFndRawEqp *tof = 0;
TFndRawSil *ism = 0;
TFndRawSil *osm = 0;
TFndRawEqp *lmd = 0;
TFndRawEqp *stb = 0;

Bhdr = rdtt->Branch("hdr","TFndHHdr",&hdr,64000,0);
Bdet[0] = rdtt->Branch("gts","TFndRawEqp",&gts,64000,0);
Bdet[1] = rdtt->Branch("tof","TFndRawEqp",&tof,64000,0);
Bdet[2] = rdtt->Branch("ism","TFndRawSil",&ism,64000,0);
Bdet[3] = rdtt->Branch("osm","TFndRawSil",&osm,64000,0);
Bdet[4] = rdtt->Branch("lmd","TFndRawEqp",&lmd,64000,0);
Bdet[5] = rdtt->Branch("stb","TFndRawEqp",&stb,64000,0);

Int_t bsize = 6400;
Int_t split = 1;
TBranch *b = hdtt->Branch("fndhdt","TFndHdt",&fndhdt,bsize,split);

// connect to mSQL database

char *host = argv[1];
cout << "mSQL host is " << host << endl;

TFndFeeMap *fndfeemap = new TFndFeeMap(host);
if(fndfeemap->IsThere()) fndfeemap->Print();

UInt_t evlen=-1;
UInt_t ec=0;
Int_t istop = 0;
UInt_t *raw;
if(onlflg) {
Int_t one=1,n;
ioctl(fSockId ,FIONBIO,&one);
raw = new UInt_t[rawsize];
}
Int_t RefRunNumber = 0;
while (istop == 0) {
ec++;
cout << "process event " << ec;
if(!onlflg) {
if(fread(&evlen, sizeof(UInt_t), 1 , f)!=1) {
istop = 1;
continue;
}
evlen = host2net(evlen);
raw = new UInt_t[evlen];
raw[0] = evlen;
cout << ", length " << evlen << endl;
if (1+fread(raw+1, sizeof(UInt_t), evlen-1, f) !=evlen) break;
}

if(onlflg) {
struct sockaddr_in claddr;
Int_t addrlen = sizeof(struct sockaddr_in);
bzero((char *) &claddr,sizeof(struct sockaddr_in));
evlen = -1;
while(evlen == -1) {
bzero((char *) raw,sizeof(raw));
evlen = recvfrom(fSockId,raw,rawsize*sizeof(int),0,(struct sockaddr *) &claddr,&addrlen);
usleep(10000);
}
printf(" Socket size %d Event %d addresses %X\n",evlen,raw[0],claddr.sin_addr.s_addr);
evlen = evlen/sizeof(int);
}
for (Int_t j=0; j<evlen; j++) raw[j] = host2net(raw[j]);

if(raw[13])
cout << "event 0" << endl; // next cicle if "Event 0"

// create and fill header branch

hdr = new TFndHHdr(raw);
// create GenInfo object (run general information)
Int_t RunNumber = hdr->GetRun();
if(RunNumber != RefRunNumber) {
RefRunNumber = RunNumber;
if(g) delete g;
TFndGenInfo *g = new TFndGenInfo(raw);
g->Print();
g->Write();
}

// create and fill detector branches

gts = 0;
tof = 0;
ism = 0;
osm = 0;
lmd = 0;
stb = 0;
Bhdr->Fill();
for (Int_t j=0; j<N_DET; j++) {
// cout << "detector " << j << endl;
UInt_t *det = raw[7+j]? raw+raw[7+j] : (UInt_t*) NULL;
if (det) {
if(j == 0) {
gts = new TFndRawEqp(raw,j);
// gts->Dump();
}
if(j == 1) {
tof = new TFndRawEqp(raw,j);
// tof->Dump();
}
if(j == 2) {
ism = new TFndRawSil(raw,j);
// ism->Dump();
}
if(j == 3) {
osm = new TFndRawSil(raw,j);
// osm->Dump();
}
if(j == 4) {
lmd = new TFndRawEqp(raw,j);
// lmd->Dump();
}
if(j == 5) {
stb = new TFndRawEqp(raw,j);
// stb->Dump();
}
// cout << "fill branch " << j << " of raw tree" << endl;
Bdet[j]->Fill();
}
}
// create TFndRdt object

fndrdt = new TFndRdt(hdr,gts,tof,ism,osm,lmd,stb);
// fndrdt->Dump();

// create TFndHdt object

// cout << "create HDT" << endl;

TFndHHdr *hdrf = new TFndHHdr(raw);
TFndTrig *fAgts = new TFndTrig(tof);
// cout << "HEADER" << hdrf << endl;
fndhdt = new TFndHdt(ec,hdrf,fAgts);

// cout << "GTS" << gts << endl;
if(gts) fndrdt->GtsTree(fndhdt,fndfeemap);
// cout << "TOF" << tof << endl;
if(tof) fndrdt->TofTree(fndhdt,fndfeemap);
// cout << "ISM " << ism << endl;
if(ism) fndrdt->IsmTree(fndhdt,fndfeemap);
// cout << "OSM " << osm << endl;
if(osm) fndrdt->OsmTree(fndhdt,fndfeemap);
// cout << "LMD " << lmd << endl;
if(lmd) fndrdt->LmdTree(fndhdt,fndfeemap);
// cout << "STB " << stb << endl;
if(stb) fndrdt->StbTree(fndhdt,fndfeemap);

// fndhdt->Dump();

Int_t nhtof = fndhdt->GetNHTof();
Int_t nhsil = fndhdt->GetNHSil();
Int_t nhlmd = fndhdt->GetNHLmd();
Int_t nhstb = fndhdt->GetNHStb();
Int_t nhtot = fndhdt->GetNHTot();

cout << nhtot << " hits in event " << ec << ": ";
cout << nhsil << " sil_hits, " << nhtof << " tof_hits, " << nhlmd << " lmd_hits, " << nhstb << " stb_hits" << endl;

hdtt->Fill();

if(!(ec%(TFndConst::kCHECK/kSCALE))) {
cout << "store on output file at event " << ec << endl;
hdr->Print();
hdtt->Print();
rdtt->Print();
of->Write();
of->cd();
of->Purge();
}
// cout << "delete hdt and rdt" << endl;
delete fndrdt;
delete fndhdt;

if(!onlflg) delete [] raw;
}
// Write Events & database information
fndfeemap->Write();

of->Write();
of->cd();
of->Purge();
// Close output file
of->Close();
}

3. TFndHLmd.h

#ifndef FIN_FndHLmd
#define FIN_FndHLmd

//_____________________________________________________________________
//
// TFndHLmd
//
// Description of the hit on Lmd
//

#include "TObject.h"
#include "TMarker3DBox.h"
#include "TFndConst.h"

class TFndHLmd : public TObject {

protected:
Int_t Cham; // Drift Chamber Identifier
Int_t Wire; // Wire Number
Int_t Tdc[2]; // TDC Values ([0]:left [1]:right)
Int_t Adc[2]; // ADC Values ([0]:left [1]:right)
Float_t x_c; // x center coordinate
Float_t y_c; // y center coordinate
Float_t z_c; // z center coordinate
Float_t x_l; // x local coordinate
Float_t y_l; // y local coordinate
Float_t z_l; // z local coordinate
Float_t x_g; // x global coordinate
Float_t y_g; // y global coordinate
Float_t z_g; // z global coordinate
TMarker3DBox *hmarker; // Marker for Event Display

public:
TFndHLmd(Int_t a=0, Int_t b=0, Int_t c=0, Int_t e=0);
~TFndHLmd();

Int_t GetCham() const { return Cham; } // Get DC Number
Int_t GetWire() const { return Wire; } // Get Wire Number

Int_t GetTdcL() const { return Tdc[0]; } // Get Left TDC
Int_t GetTdcR() const { return Tdc[1]; } // Get Right TDC
Int_t GetAdcL() const { return Adc[0]; } // Get Left ADC
Int_t GetAdcR() const { return Adc[1]; } // Get Right ADC

Float_t GetX() const { return x_g; } // Get X
Float_t GetY() const { return y_g; } // Get Y
Float_t GetZ() const { return z_g; } // Get Z
TMarker3DBox *GetMarker() const { return hmarker; } // Get Marker

void SetTdcL(Int_t);
void SetTdcR(Int_t);
void SetAdcL(Int_t);
void SetAdcR(Int_t);

void Draw(char *);

// void MzBook(); // Book and Fill the FIDARC Zebra bank for Lmd Hits
void Print(); // Print the Lmd Hit

ClassDef(TFndHLmd,2) // The LMD hit
};

#endif

4. TFndHLmd.C

#include <iostream.h>

#include "cfortran.h"

#include "TFndZebini.h"
#include "TMath.h"
#include "TFndHLmd.h"

ClassImp(TFndHLmd);

TFndHLmd::TFndHLmd(Int_t a, Int_t b, Int_t c, Int_t e) {
Cham = a;
Wire = b;
Tdc[0] = 0;
Tdc[1] = 0;
Adc[0] = 0;
Adc[1] = 0;

if (e == 3){
Tdc[0] = c;
} else if (e == 4){
Tdc[1] = c;
} else if (e == 1){
Adc[0] = c;
} else if (e == 2){
Adc[1] = c;
}

Int_t n = a/10 -1;
Double_t rad = TFndConst::kRADLMD[n];
Double_t fof = (1 - n)*TMath::Pi()*TFndConst::kROTANGLE/180.;
Double_t angin = TMath::ATan2(TFndConst::kY0[n],TFndConst::kX0[n])+fof;
Double_t angle = angin + (a - (n+1)*10)*(TMath::Pi()/4.);
x_c = rad*TMath::Cos(angle);
y_c = rad*TMath::Sin(angle);
// Double_t len = 2.5;
// z_c = 0.5*len*(((float)Adc[0]-Adc[1])/(Adc[0]+Adc[1]));
z_c = 0.;
// to be updated
x_g = x_c;
y_g = y_c;
z_g = z_c;
hmarker = new TMarker3DBox(x_g,y_g,z_g,0.1,0.1,0.1,0.,0.);
}

TFndHLmd::~TFndHLmd() {

delete hmarker;

}

void TFndHLmd::SetAdcR(Int_t adcR) {
Adc[1] = adcR;
}

void TFndHLmd::SetAdcL(Int_t adcL) {
Adc[0] = adcL;
}

void TFndHLmd::SetTdcR(Int_t tdcR) {
Tdc[1] = tdcR;
}

void TFndHLmd::SetTdcL(Int_t tdcL) {
Tdc[0] = tdcL;
}
void TFndHLmd::Draw(char *opt) {
hmarker->SetLineColor(2);
hmarker->SetFillColor(2);
hmarker->SetFillStyle(3);
if (opt == "L"){
x_g = x_g - x_c;
y_g = y_g - y_c;
z_g = z_g - z_c;
}
hmarker->SetPosition(x_g,y_g,z_g);

hmarker->Draw();
}

/*
void TFndHLmd::MzBook() {

Int_t *lq = &Zebini.jfrdt;
Int_t *iq = lq+8;
Int_t *q = lq+8;

Int_t jb=-4;
char* chid = "DCH1";
Int_t nl=0;
Int_t ns=0;
Int_t nd=9;
Int_t iod=2;
Int_t nz=0;
Int_t ldch1=0;

cout << "call MzBooki, lq = " << lq << endl;

mzbook_(&Zebini.ixdst ,&ldch1 ,&Zebini.jfges ,&jb ,&chid ,&nl ,&ns ,&nd ,&iod,&nz);

*(iq+ldch1) = Cham;
*(iq+ldch1+1) = Wire;
*(iq+ldch1+2) = 0;
*(iq+ldch1+3) = 0;
*(iq+ldch1+4) = 0;
*(iq+ldch1+5) = Tdc[0];
*(iq+ldch1+6) = Tdc[1];
*(iq+ldch1+7) = Adc[0];
*(iq+ldch1+8) = Adc[1];

for(Int_t i=0; i<9; i++) cout << "ldch1+" << i << " = " << *(iq+ldch1+i) << endl;

}
*/

void TFndHLmd::Print() {
cout << "LMD Hit: ";
cout << "DC " << Cham << ", ";
cout << "Wire " << Wire << endl;
cout << "L/R ADC: " << Adc[0] << ", " << Adc[1] << ", ";
cout << "L/R TDC: " << Tdc[0] << ", " << Tdc[1] << endl;
printf("x_c %f, y_c %f, z_c %f\n",x_c,y_c,z_c);
printf("x_l %f, y_l %f, z_l %f\n",x_l,y_l,z_l);
printf("x_g %f, y_g %f, z_g %f\n",x_g,y_g,z_g);
}

void TFndHLmd::Streamer(TBuffer &R__b) {
// Stream an object of class TFndHLmd.

if (R__b.IsReading()) {
Version_t R__v = R__b.ReadVersion(); if (R__v) { }
TObject::Streamer(R__b);
R__b >> Cham;
R__b >> Wire;
R__b.ReadStaticArray(Tdc);
R__b.ReadStaticArray(Adc);
R__b >> x_c;
R__b >> y_c;
R__b >> z_c;
if(R__v > 1) {
R__b >> x_l;
R__b >> y_l;
R__b >> z_l;
R__b >> x_g;
R__b >> y_g;
R__b >> z_g;
}
R__b >> hmarker;
} else {
R__b.WriteVersion(TFndHLmd::IsA());
TObject::Streamer(R__b);
R__b << Cham;
R__b << Wire;
R__b.WriteArray(Tdc, 2);
R__b.WriteArray(Adc, 2);
R__b << x_c;
R__b << y_c;
R__b << z_c;
R__b << x_l;
R__b << y_l;
R__b << z_l;
R__b << x_g;
R__b << y_g;
R__b << z_g;
R__b << hmarker;
}
}