Int_t THaScaler::LoadData(const THaEvData& evdata) { // Load data from THaEvData object. Return of 0 is ok. // Note: GetEvBuffer is no faster than evdata.Get... static int ldebug = 0; static Int_t data[2*SCAL_NUMBANK*SCAL_NUMCHAN+100]; new_load = kFALSE; Int_t nlen = 0; if (evstr_type == 1) { // data in the event stream (physics triggers) if (!evdata.IsPhysicsTrigger()) return 0; nlen = evdata.GetRocLength(crate); if (nlen == 0) return 0; } else { // traditional scaler event type 140 if (evdata.GetEvType() != 140) return 0; nlen = evdata.GetEvLength(); } if (ldebug) cout << "Loading evdata, bank = "<<bankgroup<<" "<<evstr_type<<" "<<crate<<" "<<evdata.GetEvType()<<" "<<nlen<<endl; Int_t maxlen = sizeof(data)/sizeof(Int_t); if (nlen > maxlen) nlen = maxlen; for (Int_t i = 0; i < nlen; i++) { if (evstr_type == 1) { data[i] = evdata.GetRawData(crate, i); } else { data[i] = evdata.GetRawData(i); } if (ldebug) { cout << " data["<<i<<"] = "<<data[i]<<" =0x"<<hex<<data[i]<<dec<<endl; } } ExtractRaw(data,nlen); return 0; };
int main(int argc, char* argv[]) { int debug=0; if (argc > 1) debug=1; // CODA file "snippet.dat" is a disk file of CODA data. THaCodaFile datafile; // We could also open the data using a // different constructor: // THaCodaFile datafile("snippet.dat"); TString filename("snippet.dat"); if (datafile.codaOpen(filename) != S_SUCCESS) { cout << "ERROR: Cannot open CODA data" << endl; exit(0); } THaEvData *evdata = new THaCodaDecoder(); // Loop over events int NUMEVT=100; int ievent; for (ievent=0; ievent<NUMEVT; ievent++) { int status = datafile.codaRead(); if ( status != S_SUCCESS ) { if ( status == EOF) { cout << "This is normal end of file. Goodbye !" << endl; } else { cout << hex << "ERROR: codaRread status = " << status << endl; } goto Finish; } // load_evbuffer() must be called each event before you access evdata contents. // If you use the version of load_evbuffer() shown here, // evdata uses its private crate map (recommended). // Alternatively you could use load_evbuffer(int* evbuffer, haCrateMap& map) evdata->LoadEvent( datafile.getEvBuffer() ); cout << "\nEvent type " << dec << evdata->GetEvType() << endl; cout << "Event number " << evdata->GetEvNum() << endl; cout << "Event length " << evdata->GetEvLength() << endl; if (evdata->IsPhysicsTrigger() ) { // triggers 1-14 cout << "Physics trigger " << endl; } if(evdata->IsScalerEvent()) cout << "Scaler `event' " << endl; // Now we want data from a particular crate and slot. // E.g. crates are 1,2,3,13,14,15 (roc numbers), Slots are 1,2,3... // This is like what one might do in a detector decode() routine. int crate = 1; // for example int slot = 24; // Here are raw 32-bit CODA words for this crate and slot cout << "Raw Data Dump for crate "<<dec<<crate<<" slot "<<slot<<endl; int hit; for(hit=0; hit<evdata->GetNumRaw(crate,slot); hit++) { cout<<dec<<"raw["<<hit<<"] = "; cout<<hex<<evdata->GetRawData(crate,slot,hit)<<endl; } // You can alternatively let evdata print out the contents of a crate and slot: evdata->PrintSlotData(crate,slot); if (evdata->IsPhysicsTrigger()) { // Below are interpreted data, device types are ADC, TDC, or scaler. // One needs to know the channel number within the device int channel = 7; // for example cout << "Device type = "; cout << evdata->DevType(crate,slot) << endl; for (hit=0; hit<evdata->GetNumHits(crate,slot,channel); hit++) { cout << "Channel " <<dec<<channel<<" hit # "<<hit<<" "; cout << "data = " << evdata->GetData(crate,slot,channel,hit)<<endl; } // Helicity data cout << "Helicity on left spectrometer "<<evdata->GetHelicity("left")<<endl; cout << "Helicity on right spectrometer "<<evdata->GetHelicity("right")<<endl; cout << "Helicity "<<evdata->GetHelicity()<<endl; } // Scalers: Although the getData methods works if you happen // to know what crate & slot contain scaler data, here is // another way to get scalers directly from evdata for (slot=0; slot<5; slot++) { cout << "\n scaler slot -> " << dec << slot << endl;; for (int chan=0; chan<16; chan++) { cout << "Scaler chan " << chan << " "; cout << evdata->GetScaler("left",slot,chan); cout << " " << evdata->GetScaler(7,slot,chan) << endl; } } } // end of event loop Finish: cout<<"\nAll done; processed "<<dec<<ievent<<" events"<<endl; }
//_____________________________________________________________________________ Int_t THaVDCPlane::Decode( const THaEvData& evData ) { // Converts the raw data into hit information // Logical wire numbers a defined by the detector map. Wire number 0 // corresponds to the first defined channel, etc. // TODO: Support "reversed" detector map modules a la MWDC if (!evData.IsPhysicsTrigger()) return -1; // the event's T0-shift, due to the trigger-type // only an issue when adding in un-retimed trigger types Double_t evtT0=0; if ( fglTrg && fglTrg->Decode(evData)==kOK ) evtT0 = fglTrg->TimeOffset(); Int_t nextHit = 0; bool only_fastest_hit = false, no_negative = false; if( fVDC ) { // If true, add only the first (earliest) hit for each wire only_fastest_hit = fVDC->TestBit(THaVDC::kOnlyFastest); // If true, ignore negative drift times completely no_negative = fVDC->TestBit(THaVDC::kIgnoreNegDrift); } // Loop over all detector modules for this wire plane for (Int_t i = 0; i < fDetMap->GetSize(); i++) { THaDetMap::Module * d = fDetMap->GetModule(i); // Get number of channels with hits Int_t nChan = evData.GetNumChan(d->crate, d->slot); for (Int_t chNdx = 0; chNdx < nChan; chNdx++) { // Use channel index to loop through channels that have hits Int_t chan = evData.GetNextChan(d->crate, d->slot, chNdx); if (chan < d->lo || chan > d->hi) continue; //Not part of this detector // Wire numbers and channels go in the same order ... Int_t wireNum = d->first + chan - d->lo; THaVDCWire* wire = GetWire(wireNum); if( !wire || wire->GetFlag() != 0 ) continue; // Get number of hits for this channel and loop through hits Int_t nHits = evData.GetNumHits(d->crate, d->slot, chan); Int_t max_data = -1; Double_t toff = wire->GetTOffset(); for (Int_t hit = 0; hit < nHits; hit++) { // Now get the TDC data for this hit Int_t data = evData.GetData(d->crate, d->slot, chan, hit); // Convert the TDC value to the drift time. // Being perfectionist, we apply a 1/2 channel correction to the raw // TDC data to compensate for the fact that the TDC truncates, not // rounds, the data. Double_t xdata = static_cast<Double_t>(data) + 0.5; Double_t time = fTDCRes * (toff - xdata) - evtT0; // If requested, ignore hits with negative drift times // (due to noise or miscalibration). Use with care. // If only fastest hit requested, find maximum TDC value and record the // hit after the hit loop is done (see below). // Otherwise just record all hits. if( !no_negative || time > 0.0 ) { if( only_fastest_hit ) { if( data > max_data ) max_data = data; } else new( (*fHits)[nextHit++] ) THaVDCHit( wire, data, time ); } // Count all hits and wires with hits // fNWiresHit++; } // End hit loop // If we are only interested in the hit with the largest TDC value // (shortest drift time), it is recorded here. if( only_fastest_hit && max_data>0 ) { Double_t xdata = static_cast<Double_t>(max_data) + 0.5; Double_t time = fTDCRes * (toff - xdata) - evtT0; new( (*fHits)[nextHit++] ) THaVDCHit( wire, max_data, time ); } } // End channel index loop } // End slot loop // Sort the hits in order of increasing wire number and (for the same wire // number) increasing time (NOT rawtime) fHits->Sort(); if ( fDebug > 3 ) { printf("\nVDC %s:\n",GetPrefix()); int ncol=4; for (int i=0; i<ncol; i++) { printf(" Wire TDC "); } printf("\n"); for (int i=0; i<(nextHit+ncol-1)/ncol; i++ ) { for (int c=0; c<ncol; c++) { int ind = c*nextHit/ncol+i; if (ind < nextHit) { THaVDCHit* hit = static_cast<THaVDCHit*>(fHits->At(ind)); printf(" %3d %5d ",hit->GetWireNum(),hit->GetRawTime()); } else { // printf("\n"); break; } } printf("\n"); } } return 0; }