////////////////////////////////////////////////////////////////////////////// // // // THaScintillatorPlane // // // // Class for trigger plane consisting of multiple // // paddles with phototubes on both ends. // // // /////////////////////////////////////////////////////////////////////////////// #include #include #include #include "THaScintillatorPlane.h" #include "THaEvData.h" #include "THaDetMap.h" #include "VarDef.h" #include "VarType.h" #include "THaTrack.h" #include "TClonesArray.h" #include "TMath.h" #include "THaNAScintHit.h" #include "THaNA.h" #include "THaTrackProj.h" // #include "THaDB.h" using namespace std; //____________________________________________________________________________ THaScintillatorPlane::THaScintillatorPlane( const char* name, const char* description, THaApparatus* apparatus ) : THaPlane(name, description, apparatus) { fHits = new TClonesArray("THaNAScintHit", 200); // Constructor // fTWalkPar = 0; // Constructor has not initialization at this point // fTrackProj = new TClonesArray( "THaTrackProj", 5 ); } Int_t THaScintillatorPlane::ReadDatabase( const TDatime& date ) { // Read this detector's parameters from the database file 'fi'. // This function is called by THaDetectorBase::Init() once at the // beginning of the analysis. // 'date' contains the date/time of the run being analyzed. static const char* const here = "ReadDatabase()"; const int LEN = 200; char buf[LEN]; Int_t nelem; // Read data from database FILE* fi = OpenFile( date ); if( !fi ) return kFileError; // Search for any date tags that follow, and start reading from // the best matching tag if any are found. If none found, but we have a // configuration string, search for it. if( SeekDBdate( fi, date ) == 0 && fConfig.Length() > 0 && SeekDBconfig( fi, fConfig.Data() )); while ( ReadComment( fi, buf, LEN ) ); fscanf ( fi, "%d", &nelem ); // Number of paddles fgets ( buf, LEN, fi ); // Reinitialization only possible for same basic configuration if( fIsInit && nelem != fNelem ) { Error( Here(here), "Cannot re-initalize with different number of paddles. " "(was: %d, now: %d). Detector not re-initialized.", fNelem, nelem ); return kInitError; } fNelem = nelem; // Read detector map. Unless a model-number is given // for the detector type, this assumes that the first half of the entries // is for ADCs and the second half, for TDCs while ( ReadComment( fi, buf, LEN ) ); int i = 0; fDetMap->Clear(); while (1) { int pos; Int_t first_chan, model; Int_t crate, slot, first, last; fgets ( buf, LEN, fi ); sscanf( buf, "%d%d%d%d%d%n", &crate, &slot, &first, &last, &first_chan, &pos ); if( crate < 0 ) break; model=atoi(buf+pos); // if there is no model number given, set to zero if( fDetMap->AddModule( crate, slot, first, last, first_chan, model ) < 0 ) { Error( Here(here), "Too many DetMap modules (maximum allowed - %d).", THaDetMap::kDetMapSize); fclose(fi); return kInitError; } } while ( ReadComment( fi, buf, LEN ) ); if( !fIsInit ) { fIsInit = true; } // Dimension of arrays fLT = new Double_t[fNelem]; fRT = new Double_t[fNelem]; fLToff = new Double_t[fNelem]; fRToff = new Double_t[fNelem]; fLT_c = new Double_t[fNelem]; fRT_c = new Double_t[fNelem]; fLA = new Double_t[fNelem]; fRA = new Double_t[fNelem]; fLAped = new Double_t[fNelem]; fRAped = new Double_t[fNelem]; fLAgain = new Double_t[fNelem]; fRAgain = new Double_t[fNelem]; fLA_c = new Double_t[fNelem]; fRA_c = new Double_t[fNelem]; fTDiff = new Double_t[fNelem]; fYPos = new Double_t[fNelem]; fYBar = new Double_t[fNelem]; fXBar = new Double_t[fNelem]; fZBar = new Double_t[fNelem]; fDist = new Double_t[fNelem]; fTOFOffset = new Double_t[fNelem]; fTOFScale = new Double_t[fNelem]; fYOffset = new Double_t[fNelem]; fYScale = new Double_t[fNelem]; fTOF = new Double_t[fNelem]; fIsHit = new Bool_t[fNelem]; fNRHits = new Int_t[fNelem]; fNLHits = new Int_t[fNelem]; fMultiHits = new PaddleMultiHits[fNelem]; fIBlockingBarMin = new Int_t[fNelem]; fIBlockingBarMax = new Int_t[fNelem]; // Read calibration data while ( ReadComment( fi, buf, LEN ) );// TDC time offsets Float_t nL,nR,nD; for (i=0;iClear(); } //_____________________________________________________________________________ Int_t THaScintillatorPlane::Decode( const THaEvData& evdata ) { // Decode scintillator data, correct TDC times and ADC amplitudes, and copy // the data to the local data members. // This implementation makes the following assumptions about the detector map: // - The first half of the map entries corresponds to ADCs, // the second half, to TDCs. // - The first fNelem detector channels correspond to the PMTs on the // right hand side, the next fNelem channels, to the left hand side. // (Thus channel numbering for each module must be consecutive.) ClearEvent(); Int_t nextHit=0; // static const Double_t target_dist = 6.04; //THaNA* app = static_cast(fApparatus); THaNA* app = static_cast(GetApparatus()); Double_t Dist2trg = app->GetDistance(); // cout <<"Distance, "<< Dist2trg<<", "<GetSize(); i++ ) { THaDetMap::Module* d = fDetMap->GetModule( i ); bool adc = (i < fDetMap->GetSize()/2); // Loop over all channels that have a hit. 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->lo || chan > d->hi ) continue; // Not one of my channels // Get the detector channel number, starting at 0 Int_t k = d->first + chan - d->lo - 1; #ifdef WITH_DEBUG if( k<0 || k>NDEST*fNelem ) { // Indicates bad database Warning( Here("Decode()"), "Illegal detector channel: %d", k ); continue; } // cout << "adc,j,k = " <crate, d->slot, chan, 0 ); if( adc ) { Int_t data = evdata.GetData( d->crate, d->slot, chan, 0 ); dest->adc[k] = static_cast( data ); (*dest->nahit)++; } else { dest->tdc[k] = static_cast( data ); (*dest->nthit)++; } // end if // Handles Multihit in TDCs if (!adc) { Int_t nHits = evdata.GetNumHits(d->crate,d->slot,chan); if (kbefore == k) { fNLHits[k]=nHits; } else { fNRHits[k]=nHits; } for (Int_t hit=0; hitcrate, d->slot, chan, hit); if (kbefore == k) { fMultiHits[k].AddLeftHit(data); } else { fMultiHits[k].AddRightHit(data); } } // end multihit loop } //end if !adc } // end for loop } for(Int_t i=0;i0 && fMultiHits[i].GetNRHits()>0&&fLA_c[i]>0 && fRA_c[i]>0); // 30.08.2005 (saw) Remove ADC requirement for now fIsHit[i]=(fMultiHits[i].GetNLHits()>0 && fMultiHits[i].GetNRHits()>0); // Feb 17,2006 (ramesh) accept adc window. // fIsHit[i]=(fMultiHits[i].GetNLHits()>0 && fMultiHits[i].GetNRHits()>0&&fLA_c[i]>0 && fRA_c[i]>0); if (fIsHit[i]) { fDist[i] = sqrt(fXBar[i]*fXBar[i]+fYBar[i]*fYBar[i]+(fZBar[i] + Dist2trg)*(fZBar[i] + Dist2trg)); for (Int_t ii=0; ii-2000. && ypos<2000.) { // new( (*fHits)[nextHit++] ) THaNAScintHit( i, ypos, tof, energy ); // fYPos[i]=ypos; // } //////////////////////////////////////////////// ///////////////////////////////////////////////////// Double_t ypos = -300.; if ( left>0 && right>0 ) { ypos = 100.*((left-right)+fYOffset[i]-fYScale[i]/2.)/fYScale[i]; if (ypos>-100. && ypos<100.) { new( (*fHits)[nextHit++] ) THaNAScintHit( i, ypos, tof, energy ); fYPos[i]=ypos; } } // end if ypos //////////////////////////////////////////////////// } // end for jj } // end for ii } // end if IsHit } // end for i HitCount(); return fLTNhit+fRTNhit; } //_____________________________________________________________________________ Int_t THaScintillatorPlane::CoarseProcess( TClonesArray& tracks ) { HitCount(); return 0; } //_____________________________________________________________________________ Int_t THaScintillatorPlane::FineProcess( TClonesArray& tracks ) { return 0; } //_____________________________________________________________________________ Bool_t THaScintillatorPlane::IsHit() { int i=0; bool Success = fIsHit[0]; while (!Success && i