#include "THaShower.h"
#include "THaGlobals.h"
#include "THaEvData.h"
#include "THaDetMap.h"
#include "VarDef.h"
#include "VarType.h"
#include "THaTrack.h"
#include "TClonesArray.h"
#include "TDatime.h"
#include "TMath.h"
#include <cstring>
#include <iostream>
ClassImp(THaShower)
using namespace std;
THaShower::THaShower( const char* name, const char* description,
THaApparatus* apparatus ) :
THaPidDetector(name,description,apparatus), fNChan(NULL), fChanMap(NULL)
{
}
Int_t THaShower::ReadDatabase( const TDatime& date )
{
static const char* const here = "ReadDatabase()";
const int LEN = 100;
char buf[LEN];
Int_t nelem, ncols, nrows, nclbl;
FILE* fi = OpenFile( date );
if( !fi ) return kFileError;
fgets ( buf, LEN, fi ); fgets ( buf, LEN, fi );
fscanf ( fi, "%d%d", &ncols, &nrows );
nelem = ncols * nrows;
nclbl = TMath::Min( 3, nrows ) * TMath::Min( 3, ncols );
if( fIsInit && (nelem != fNelem || nclbl != fNclublk) ) {
Error( Here(here), "Cannot re-initalize with different number of blocks or "
"blocks per cluster. Detector not re-initialized." );
fclose(fi);
return kInitError;
}
if( nrows <= 0 || ncols <= 0 || nclbl <= 0 ) {
Error( Here(here), "Illegal number of rows or columns: "
"%d %d", nrows, ncols );
fclose(fi);
return kInitError;
}
fNelem = nelem;
fNrows = nrows;
fNclublk = nclbl;
UShort_t mapsize = fDetMap->GetSize();
delete [] fNChan;
if( fChanMap ) {
for( UShort_t i = 0; i<mapsize; i++ )
delete [] fChanMap[i];
}
delete [] fChanMap;
fDetMap->Clear();
fgets ( buf, LEN, fi ); fgets ( buf, LEN, fi );
while (1) {
Int_t crate, slot, first, last;
fscanf ( fi,"%d%d%d%d", &crate, &slot, &first, &last );
fgets ( buf, LEN, fi );
if( crate < 0 ) break;
if( fDetMap->AddModule( crate, slot, first, last ) < 0 ) {
Error( Here(here), "Too many DetMap modules (maximum allowed - %d).",
THaDetMap::kDetMapSize);
fclose(fi);
return kInitError;
}
}
mapsize = fDetMap->GetSize();
if( mapsize == 0 ) {
Error( Here(here), "No modules defined in detector map.");
fclose(fi);
return kInitError;
}
fNChan = new UShort_t[ mapsize ];
fChanMap = new UShort_t*[ mapsize ];
for( UShort_t i=0; i < mapsize; i++ ) {
THaDetMap::Module* module = fDetMap->GetModule(i);
fNChan[i] = module->hi - module->lo + 1;
if( fNChan[i] > 0 )
fChanMap[i] = new UShort_t[ fNChan[i] ];
else {
Error( Here(here), "No channels defined for module %d.", i);
delete [] fNChan; fNChan = NULL;
for( UShort_t j=0; j<i; j++ )
delete [] fChanMap[j];
delete [] fChanMap; fChanMap = NULL;
fclose(fi);
return kInitError;
}
}
fgets ( buf, LEN, fi );
*buf = '\0';
char *ptr=buf;
int nchar=0;
for ( UShort_t i = 0; i < mapsize; i++ ) {
for ( UShort_t j = 0; j < fNChan[i]; j++ ) {
while ( !strpbrk(ptr,"0123456789") ) {
fgets ( buf, LEN, fi );
if( (ptr = strchr(buf,'#')) ) *ptr = '\0';
ptr = buf;
nchar=0;
}
sscanf (ptr, "%hu%n", *(fChanMap+i)+j, &nchar );
ptr += nchar;
}
}
fgets ( buf, LEN, fi );
Float_t x,y,z;
fscanf ( fi, "%f%f%f", &x, &y, &z );
fOrigin.SetXYZ( x, y, z );
fgets ( buf, LEN, fi ); fgets ( buf, LEN, fi );
fscanf ( fi, "%f%f%f", fSize, fSize+1, fSize+2 );
fgets ( buf, LEN, fi ); fgets ( buf, LEN, fi );
Float_t angle;
fscanf ( fi, "%f", &angle );
fgets ( buf, LEN, fi ); fgets ( buf, LEN, fi );
const Double_t degrad = TMath::Pi()/180.0;
tan_angle = TMath::Tan(angle*degrad);
sin_angle = TMath::Sin(angle*degrad);
cos_angle = TMath::Cos(angle*degrad);
DefineAxes(angle*degrad);
if( !fIsInit ) {
fBlockX = new Float_t[ fNelem ];
fBlockY = new Float_t[ fNelem ];
fPed = new Float_t[ fNelem ];
fGain = new Float_t[ fNelem ];
fA = new Float_t[ fNelem ];
fA_p = new Float_t[ fNelem ];
fA_c = new Float_t[ fNelem ];
fNblk = new Int_t[ fNclublk ];
fEblk = new Float_t[ fNclublk ];
fIsInit = true;
}
fscanf ( fi, "%f%f", &x, &y );
fgets ( buf, LEN, fi ); fgets ( buf, LEN, fi );
Float_t dx, dy;
fscanf ( fi, "%f%f", &dx, &dy );
fgets ( buf, LEN, fi ); fgets ( buf, LEN, fi );
fscanf ( fi, "%f", &fEmin );
fgets ( buf, LEN, fi );
if( SeekDBdate( fi, date ) == 0 && fConfig.Length() > 0 &&
SeekDBconfig( fi, fConfig.Data() )) {}
fgets ( buf, LEN, fi );
if( buf[0] == '[' ) fgets ( buf, LEN, fi );
for (int j=0; j<fNelem; j++)
fscanf (fi,"%f",fPed+j);
fgets ( buf, LEN, fi ); fgets ( buf, LEN, fi );
for (int j=0; j<fNelem; j++)
fscanf (fi, "%f",fGain+j);
for( int c=0; c<ncols; c++ ) {
for( int r=0; r<nrows; r++ ) {
int k = nrows*c + r;
fBlockX[k] = x + r*dx;
fBlockY[k] = y + c*dy;
}
}
fclose(fi);
return kOK;
}
Int_t THaShower::DefineVariables( EMode mode )
{
if( mode == kDefine && fIsSetup ) return kOK;
fIsSetup = ( mode == kDefine );
RVarDef vars[] = {
{ "nhit", "Number of hits", "fNhits" },
{ "a", "Raw ADC amplitudes", "fA" },
{ "a_p", "Ped-subtracted ADC amplitudes", "fA_p" },
{ "a_c", "Calibrated ADC amplitudes", "fA_c" },
{ "asum_p", "Sum of ped-subtracted ADCs", "fAsum_p" },
{ "asum_c", "Sum of calibrated ADCs", "fAsum_c" },
{ "nclust", "Number of clusters", "fNclust" },
{ "e", "Energy (MeV) of largest cluster", "fE" },
{ "x", "x-position (cm) of largest cluster", "fX" },
{ "y", "y-position (cm) of largest cluster", "fY" },
{ "mult", "Multiplicity of largest cluster", "fMult" },
{ "nblk", "Numbers of blocks in main cluster", "fNblk" },
{ "eblk", "Energies of blocks in main cluster", "fEblk" },
{ "trx", "track x-position in det plane", "fTRX" },
{ "try", "track y-position in det plane", "fTRY" },
{ 0 }
};
return DefineVarsFromList( vars, mode );
}
THaShower::~THaShower()
{
if( fIsSetup )
RemoveVariables();
if( fIsInit )
DeleteArrays();
}
void THaShower::DeleteArrays()
{
delete [] fNChan; fNChan = 0;
UShort_t mapsize = fDetMap->GetSize();
if( fChanMap ) {
for( UShort_t i = 0; i<mapsize; i++ )
delete [] fChanMap[i];
}
delete [] fChanMap; fChanMap = 0;
delete [] fBlockX; fBlockX = 0;
delete [] fBlockY; fBlockY = 0;
delete [] fPed; fPed = 0;
delete [] fGain; fGain = 0;
delete [] fA; fA = 0;
delete [] fA_p; fA_p = 0;
delete [] fA_c; fA_c = 0;
delete [] fNblk; fNblk = 0;
delete [] fEblk; fEblk = 0;
}
inline
void THaShower::ClearEvent()
{
const int lsh = fNelem*sizeof(Float_t);
const int lsc = fNclublk*sizeof(Float_t);
const int lsi = fNclublk*sizeof(Int_t);
fNhits = 0;
memset( fA, 0, lsh );
memset( fA_p, 0, lsh );
memset( fA_c, 0, lsh );
fAsum_p = 0.0;
fAsum_c = 0.0;
fNclust = 0;
fE = 0.0;
fX = 0.0;
fY = 0.0;
fMult = 0;
memset( fNblk, 0, lsi );
memset( fEblk, 0, lsc );
fTRX = 0.0;
fTRY = 0.0;
}
Int_t THaShower::Decode( const THaEvData& evdata )
{
ClearEvent();
for( UShort_t i = 0; i < fDetMap->GetSize(); i++ ) {
THaDetMap::Module* d = fDetMap->GetModule( i );
for( Int_t j = 0; j < evdata.GetNumChan( d->crate, d->slot ); j++) {
Int_t chan = evdata.GetNextChan( d->crate, d->slot, j );
if( chan > d->hi || chan < d->lo ) continue;
Int_t data = evdata.GetData( d->crate, d->slot, chan, 0 );
Int_t k = *(*(fChanMap+i)+(chan-d->lo)) - 1;
#ifdef WITH_DEBUG
if( k<0 || k>=fNelem )
Warning( Here("Decode()"), "Bad array index: %d. Your channel map is "
"invalid. Data skipped.", k );
else
#endif
{
fA[k] = data;
fA_p[k] = data - fPed[k];
fA_c[k] = fA_p[k] * fGain[k];
if( fA_p[k] > 0.0 )
fAsum_p += fA_p[k];
if( fA_c[k] > 0.0 )
fAsum_c += fA_c[k];
fNhits++;
}
}
}
if ( fDebug > 3 ) {
printf("\nShower Detector %s:\n",GetPrefix());
int ncol=3;
for (int i=0; i<ncol; i++) {
printf(" Block ADC ADC_p ");
}
printf("\n");
for (int i=0; i<(fNelem+ncol-1)/ncol; i++ ) {
for (int c=0; c<ncol; c++) {
int ind = c*fNelem/ncol+i;
if (ind < fNelem) {
printf(" %3d %5.0f %5.0f ",ind+1,fA[ind],fA_p[ind]);
} else {
break;
}
}
printf("\n");
}
}
return fNhits;
}
Int_t THaShower::CoarseProcess( TClonesArray& tracks )
{
fNclust = 0;
short mult = 0, nr, nc, ir, ic, dr, dc;
int nmax = -1;
double emax = fEmin;
for ( int i = 0; i < fNelem; i++) {
double ei = fA_c[i];
if ( ei > emax) {
nmax = i;
emax = ei;
}
}
if ( nmax >= 0 ) {
double sxe = 0, sye = 0;
nc = nmax/fNrows;
nr = nmax%fNrows;
fNblk[mult] = nmax;
fEblk[mult++] = emax;
sxe = emax * fBlockX[nmax];
sye = emax * fBlockY[nmax];
for ( int i = 0; i < fNelem; i++) {
double ei = fA_c[i];
if ( ei>0 && i!=nmax ) {
ic = i/fNrows;
ir = i%fNrows;
dr = nr - ir;
dc = nc - ic;
if ( -2<dr&&dr<2&&-2<dc&&dc<2 ) {
fNblk[mult] = i;
fEblk[mult++] = ei;
sxe += ei * fBlockX[i];
sye += ei * fBlockY[i];
emax += ei;
}
}
}
fNclust = 1;
fE = emax;
fX = sxe/emax;
fY = sye/emax;
fMult = mult;
}
int ne_track = tracks.GetLast()+1;
if ( ne_track >= 1 && tracks.At(0) != 0 ) {
THaTrack* theTrack = static_cast<THaTrack*>( tracks[0] );
double fpe_x = theTrack->GetX();
double fpe_y = theTrack->GetY();
double fpe_th = theTrack->GetTheta();
double fpe_ph = theTrack->GetPhi();
fTRX = ( fpe_x + fpe_th * fOrigin.Z() ) /
( cos_angle * (1.0 + fpe_th * tan_angle) );
fTRY = fpe_y + fpe_ph * fOrigin.Z() - fpe_ph * sin_angle * fTRX;
}
return 0;
}
Int_t THaShower::FineProcess( TClonesArray& )
{
return 0;
}
Last change: Sat Nov 7 21:26:52 2009
Last generated: 2009-11-07 21:26
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.