diff --git a/src/THcDetMap.cxx b/src/THcDetMap.cxx index c8c38a52c5ec6fa1f4bbf72d7ab55bd152dea5c7..da3b15ab19e8fa515f550aa12e6b2f0a7b36701a 100644 --- a/src/THcDetMap.cxx +++ b/src/THcDetMap.cxx @@ -16,82 +16,17 @@ using namespace std; -const int THcDetMap::kDetMapSize; - -// FIXME: load from db_cratemap -struct ModuleType { - UInt_t model; // model identifier - Bool_t adc; // true if ADC - Bool_t tdc; // true if TDC -}; - -static const ModuleType module_list[] = { - { 1875, 0, 1 }, - { 1877, 0, 1 }, - { 1881, 1, 0 }, - { 1872, 0, 1 }, - { 3123, 1, 0 }, - { 1182, 1, 0 }, - { 792, 1, 0 }, - { 775, 0, 1 }, - { 767, 0, 1 }, - { 3201, 0, 1 }, - { 6401, 0, 1 }, - { 1190, 0, 1 }, - { 0 } -}; - -//_____________________________________________________________________________ -void THcDetMap::Module::SetModel( UInt_t m ) -{ - model = m & kModelMask; - const ModuleType* md = module_list; - while ( md->model && model != md->model ) md++; - if( md->adc ) MakeADC(); - if( md->tdc ) MakeTDC(); -} - //_____________________________________________________________________________ -void THcDetMap::Module::SetResolution( Double_t res ) -{ - resolution = res; -} - -//_____________________________________________________________________________ -THcDetMap::THcDetMap() : fNmodules(0), fMap(0), fMaplength(0) +THcDetMap::THcDetMap() : THaDetMap() { // Default constructor. Creates an empty detector map. } //_____________________________________________________________________________ -THcDetMap::THcDetMap( const THcDetMap& rhs ) +THcDetMap::THcDetMap( const THcDetMap& rhs ) : THaDetMap( rhs ) { // Copy constructor - fMaplength = rhs.fMaplength; - fNmodules = rhs.fNmodules; - if( fMaplength > 0 ) { - fMap = new Module[fMaplength]; - memcpy(fMap,rhs.fMap,fNmodules*sizeof(Module)); - } -} - -//_____________________________________________________________________________ -THcDetMap& THcDetMap::operator=( const THcDetMap& rhs ) -{ - // THcDetMap assignment operator - - if ( this != &rhs ) { - if ( fMaplength != rhs.fMaplength ) { - delete [] fMap; - fMaplength = rhs.fMaplength; - if( fMaplength > 0 ) - fMap = new Module[fMaplength]; - } - fNmodules = rhs.fNmodules; - memcpy(fMap,rhs.fMap,fNmodules*sizeof(Module)); - } - return *this; } //_____________________________________________________________________________ @@ -102,269 +37,5 @@ THcDetMap::~THcDetMap() delete [] fMap; } -//_____________________________________________________________________________ -Int_t THcDetMap::AddModule( UShort_t crate, UShort_t slot, - UShort_t chan_lo, UShort_t chan_hi, - UInt_t first, UInt_t model, Int_t refindex, - Int_t refchan ) -{ - // Add a module to the map. - - if( fNmodules >= kDetMapSize ) return -1; //Map is full - // Logical channels can run either "with" or "against" the physical channel - // numbers: - // lo<=hi : lo -> first - // hi -> first+hi-lo - // - // lo>hi : hi -> first - // lo -> first+lo-hi - // - // To indicate the second case, The flag "reverse" is set to true in the - // module. The fields lo and hi are reversed so that lo<=hi always. - // - bool reverse = ( chan_lo > chan_hi ); - - if ( fNmodules >= fMaplength ) { // need to expand the Map - Int_t oldlen = fMaplength; - fMaplength += 10; - Module* tmpmap = new Module[fMaplength]; // expand in groups of 10 - if( oldlen > 0 ) { - memcpy(tmpmap,fMap,oldlen*sizeof(Module)); - delete [] fMap; - } - fMap = tmpmap; - } - - Module& m = fMap[fNmodules]; - m.crate = crate; - m.slot = slot; - if( reverse ) { - m.lo = chan_hi; - m.hi = chan_lo; - } else { - m.lo = chan_lo; - m.hi = chan_hi; - } - m.first = first; - m.SetModel( model ); - m.refindex = refindex; - m.refchan = refchan; - m.SetResolution( 0.0 ); - m.reverse = reverse; - - return ++fNmodules; -} - -//_____________________________________________________________________________ -THcDetMap::Module* THcDetMap::Find( UShort_t crate, UShort_t slot, - UShort_t chan ) -{ - // Return the module containing crate, slot, and channel chan. - // If several matching modules exist (which mean the map is misconfigured), - // only the first one is returned. If none match, return NULL. - // Since the map is usually small and not necessarily sorted, a simple - // linear search is done. - - Module* found = NULL; - for( UShort_t i = 0; i < fNmodules; ++i ) { - Module* d = uGetModule(i); - if( d->crate == crate && d->slot == slot && - d->lo <= chan && chan <= d->hi ) { - found = d; - break; - } - } - return found; -} - -//_____________________________________________________________________________ -Int_t THcDetMap::Fill( const vector<Int_t>& values, UInt_t flags ) -{ - // Fill the map with 'values'. Depending on 'flags', the values vector - // is interpreted as a 4-, 5-, 6- or 7-tuple: - // - // The first 4 values are interpreted as (crate,slot,start_chan,end_chan) - // Each of the following flags causes one more value to be used as part of - // the tuple for each module: - // - // kFillLogicalChannel - Logical channel number for 'start_chan'. - // kFillModel - The module's hardware model number (see AddModule()) - // kFillRefChan - Reference channel (for pipeline TDCs etc.) - // kFillRefIndex - Reference index (for pipeline TDCs etc.) - // - // If more than one flag is present, the numbers will be interpreted - // in the order the flags are listed above. - // Example: - // flags = kFillModel | kFillRefChan - // ==> - // the vector is interpreted as a series of 6-tuples in the order - // (crate,slot,start_chan,end_chan,model,refchan). - // - // If kFillLogicalChannel is not set then the first logical channel numbers - // are automatically calculated for each module, assuming the numbers are - // sequential. - // - // By default, an existing map is overwritten. If the flag kDoNotClear - // is present, then the data are appended. - // - // The return value is the number of modules successfully added, - // or negative if an error occurred. - - typedef vector<Int_t>::size_type vsiz_t; - - if( (flags & kDoNotClear) == 0 ) - Clear(); - - vsiz_t tuple_size = 4; - if( flags & kFillLogicalChannel ) - tuple_size++; - if( flags & kFillModel ) - tuple_size++; - if( flags & kFillRefChan ) - tuple_size++; - if( flags & kFillRefIndex ) - tuple_size++; - - UInt_t prev_first = 0, prev_nchan = 0; - // Defaults for optional values - UInt_t first = 0, model = 0; - Int_t rchan = -1, ref = -1; - - Int_t ret = 0; - for( vsiz_t i = 0; i < values.size(); i += tuple_size ) { - // For compatibility with older maps, crate < 0 means end of data - if( values[i] < 0 ) - break; - // Now we require a full tuple - if( i+tuple_size > values.size() ) { - ret = -127; - break; - } - - vsiz_t k = 4; - if( flags & kFillLogicalChannel ) - first = values[i+k++]; - else { - first = prev_first + prev_nchan; - } - if( flags & kFillModel ) - model = values[i+k++]; - if( flags & kFillRefChan ) - rchan = values[i+k++]; - if( flags & kFillRefIndex ) - ref = values[i+k++]; - - ret = AddModule( values[i], values[i+1], values[i+2], values[i+3], - first, model, ref, rchan ); - if( ret<=0 ) - break; - prev_first = first; - prev_nchan = GetNchan( ret-1 ); - } - - return ret; -} - -//_____________________________________________________________________________ -Int_t THcDetMap::GetTotNumChan() const -{ - // Get sum of the number of channels of all modules in the map. This is - // typically the total number of hardware channels used by the detector. - - Int_t sum = 0; - for( UShort_t i = 0; i < fNmodules; i++ ) - sum += GetNchan(i); - - return sum; -} - - -//_____________________________________________________________________________ -void THcDetMap::GetMinMaxChan( Int_t& min, Int_t& max, ECountMode mode ) const -{ - // Put the minimum and maximum logical or reference channel numbers - // into min and max. If refidx is true, check refindex, else check logical - // channel numbers. - - min = kMaxInt; - max = kMinInt; - bool do_ref = ( mode == kRefIndex ); - for( UShort_t i = 0; i < fNmodules; i++ ) { - Module* m = GetModule(i); - Int_t m_min = do_ref ? m->refindex : m->first; - Int_t m_max = do_ref ? m->refindex : m->first + m->hi - m->lo; - if( m_min < min ) - min = m_min; - if( m_max > max ) - max = m_max; - } -} - - -//_____________________________________________________________________________ -void THcDetMap::Print( Option_t* ) const -{ - // Print the contents of the map - - cout << "Size: " << fNmodules << endl; - for( UShort_t i=0; i<fNmodules; i++ ) { - Module* m = GetModule(i); - cout << " " - << setw(5) << m->crate - << setw(5) << m->slot - << setw(5) << m->lo - << setw(5) << m->hi - << setw(5) << m->first - << setw(5) << GetModel(m); - if( IsADC(m) ) - cout << setw(4) << " ADC"; - if( IsTDC(m) ) - cout << setw(4) << " TDC"; - cout << setw(5) << m->refchan - << setw(5) << m->refindex - << setw(8) << m->resolution - << endl; - } -} - -//_____________________________________________________________________________ -void THcDetMap::Reset() -{ - // Clear() the map and reset the array size to zero, freeing memory. - - Clear(); - delete [] fMap; - fMap = NULL; - fMaplength = 0; -} - -//_____________________________________________________________________________ -static int compare_modules( const void* p1, const void* p2 ) -{ - // Helper function for sort - - const THcDetMap::Module* lhs = static_cast<const THcDetMap::Module*>(p1); - const THcDetMap::Module* rhs = static_cast<const THcDetMap::Module*>(p2); - - if( lhs->crate < rhs->crate ) return -1; - if( lhs->crate > rhs->crate ) return 1; - if( lhs->slot < rhs->slot ) return -1; - if( lhs->slot > rhs->slot ) return 1; - if( lhs->lo < rhs->lo ) return -1; - if( lhs->lo > rhs->lo ) return 1; - return 0; -} - -//_____________________________________________________________________________ -void THcDetMap::Sort() -{ - // Sort the map by crate/slot/low channel - - if( fMap && fNmodules ) - qsort( fMap, fNmodules, sizeof(Module), compare_modules ); - -} - //_____________________________________________________________________________ ClassImp(THcDetMap) - diff --git a/src/THcDetMap.h b/src/THcDetMap.h index f353909b355647f494f03ecd29a9afcf31d5c6e7..47d4d0f27fa1bea0e28ee27e7af88626ac2a1a88 100644 --- a/src/THcDetMap.h +++ b/src/THcDetMap.h @@ -7,11 +7,8 @@ // THcDetMap // // Standard detector map. -// The detector map defines the hardware channels that correspond to a -// single detector. Typically, "channels" are Fastbus or VMW addresses -// characterized by // -// Crate, Slot, range of channels +// Add plane and signal information to Hall A standard. // ////////////////////////////////////////////////////////////////////////// @@ -20,17 +17,10 @@ // "resolution", as well as the "model map" in AddModule. We should get it from // there - to ensure consistency and have one less maintenance headache. -#include "Rtypes.h" -#include <vector> +#include "THaDetMap.h" -class THcDetMap { +class THcDetMap : public THaDetMap { -protected: - static const UInt_t kADCBit = BIT(31); - static const UInt_t kTDCBit = BIT(30); - // Upper byte of model reserved for property bits - static const UInt_t kModelMask = 0x00ffffff; - public: struct Module { UShort_t crate; @@ -60,104 +50,17 @@ public: void MakeADC() { model |= kADCBit; } }; - // Flags for GetMinMaxChan() - enum ECountMode { - kLogicalChan = 0, - kRefIndex = 1 - }; - // Flags for Fill() - enum EFillFlags { - kDoNotClear = BIT(0), // Don't clear the map first - kFillLogicalChannel = BIT(10), // Parse the logical channel number - kFillModel = BIT(11), // Parse the model number - kFillRefIndex = BIT(12), // Parse the reference index - kFillRefChan = BIT(13) // Parse the reference channel - }; - THcDetMap(); THcDetMap( const THcDetMap& ); THcDetMap& operator=( const THcDetMap& ); virtual ~THcDetMap(); - virtual Int_t AddModule( UShort_t crate, UShort_t slot, - UShort_t chan_lo, UShort_t chan_hi, - UInt_t first=0, UInt_t model=0, - Int_t refindex=-1, Int_t refchan = -1 ); - void Clear() { fNmodules = 0; } - virtual Module* Find( UShort_t crate, UShort_t slot, UShort_t chan ); - virtual Int_t Fill( const std::vector<Int_t>& values, UInt_t flags = 0 ); - void GetMinMaxChan( Int_t& min, Int_t& max, - ECountMode mode = kLogicalChan ) const; - Module* GetModule( UShort_t i ) const ; - Int_t GetNchan( UShort_t i ) const; - Int_t GetTotNumChan() const; - Int_t GetSize() const { return static_cast<Int_t>(fNmodules); } - - UInt_t GetModel( UShort_t i ) const; - Bool_t IsADC( UShort_t i ) const; - Bool_t IsTDC( UShort_t i ) const; - static UInt_t GetModel( Module* d ); - static Bool_t IsADC( Module* d ); - static Bool_t IsTDC( Module* d ); - - virtual void Print( Option_t* opt="" ) const; - virtual void Reset(); - virtual void Sort(); - - static const int kDetMapSize = (1<<16)-1; //Sanity limit on map size - protected: - UShort_t fNmodules; // Number of modules (=crate,slot) in the map - Module* fMap; // Array of modules, each module is a 7-tuple // (create,slot,chan_lo,chan_hi,first_logical, // model,refindex) - Int_t fMaplength; // current size of the fMap array - - Module* uGetModule( UShort_t i ) const { return fMap+i; } - ClassDef(THcDetMap,0) //The standard detector map }; -inline THcDetMap::Module* THcDetMap::GetModule( UShort_t i ) const { - return i<fNmodules ? uGetModule(i) : NULL; -} - -inline Bool_t THcDetMap::IsADC(Module* d) { - if( !d ) return kFALSE; - return d->IsADC(); -} - -inline Bool_t THcDetMap::IsTDC(Module* d) { - if( !d ) return kFALSE; - return d->IsTDC(); -} - -inline UInt_t THcDetMap::GetModel(Module* d) { - if( !d ) return 0; - return d->GetModel(); -} - -inline Bool_t THcDetMap::IsADC( UShort_t i ) const { - if( i >= fNmodules ) return kFALSE; - return uGetModule(i)->IsADC(); -} - -inline Bool_t THcDetMap::IsTDC( UShort_t i ) const { - if( i >= fNmodules ) return kFALSE; - return uGetModule(i)->IsTDC(); -} - -inline UInt_t THcDetMap::GetModel( UShort_t i ) const { - if( i >= fNmodules ) return 0; - return uGetModule(i)->GetModel(); -} - -inline Int_t THcDetMap::GetNchan( UShort_t i ) const { - // Return the number of channels of the i-th module - if( i >= fNmodules ) return 0; - return uGetModule(i)->GetNchan(); -} - #endif