///////////////////////////////////////////////////////////////////////////
//                                                                        
// The LogID class contains a log ID number (encoding of detector
// element position) as well as functions to obtain the location of
// log in question. LogID is used in the CalHit class.
//                                                                        
///////////////////////////////////////////////////////////////////////////

// access and set functions for binary calorimeter tags
// Version 1.0 21 Oct 1998 Richard creation
// Version 1.1 25 Oct 1999 R.Dubois Clone from LCD

#include "LogID.h"

ClassImp(LogID)

///________________________________________________________________________
 LogID::LogID(){
    // Default constructor
    // All fields in tagword initialized to 0
    setTag(static_cast<UInt_t>(0));
}
///________________________________________________________________________
 LogID::LogID(UInt_t tag=0) {
    // Create a LogID object with number tag
    setTag(tag);
}
///________________________________________________________________________
 LogID::~LogID() {
    // Destructor
}
///________________________________________________________________________
 UInt_t LogID::getTag() const { 
    // Returns the log number
    return m_tag;
}
///________________________________________________________________________
 Bool_t LogID::isValidColumn(UInt_t columnVal) {
    // Check if given value is a valid Column number:

    return (
            ((columnVal <= BOUNDS_COLUMN) && !(columnVal & ~CAL_M_COLUMN)) ?
            kTRUE : kFALSE
           );
}
///________________________________________________________________________
 Bool_t LogID::isValidPipeLine(UInt_t pipeVal) {
    // Check if given value is a valid pipe number:

    return (
            ((pipeVal <= BOUNDS_PIPE) && !(pipeVal & ~CAL_M_PIPE)) ?
            kTRUE : kFALSE
           );
}
///________________________________________________________________________
/*
Bool_t LogID::isValidID(UInt_t idVal) {
    // Check length of idVal:
    if (idVal & CAL_M_ID)
        return kFALSE;
    
    // Check Pipeline bin:
    if (!isValidPipeLine(getPipeLine(idVal))
        return kFALSE;
}
*/
///________________________________________________________________________
 Bool_t LogID::fillGeomFromID(LogID::TAG_STRUCT *ts) {
    // fill Layer, Column fields from ID fields:
    
    if (!isValidPipeLine(ts->pipeline))
        return kFALSE;
    if (ts->sequence & ~CAL_M_SEQ)
        return kFALSE;
    if (ts->xy & ~CAL_M_XY)
        return kFALSE;
    if (ts->tower & ~CAL_M_TOWER)
        return kFALSE;

    // Calculation code copied from LogID::isValidTagWord, it should be therefore
    // moved to a single function called from both places...  (TODO)

    // seq_divisor is 1/2 the number of possible sequence values:
    UInt_t seq_divisor = 1 << (CAL_K_SEQ - 1);
    UInt_t layerVal = ((ts->sequence % seq_divisor) << CAL_K_XY) | ts->xy;
    UInt_t columnVal = ts->pipeline * 2 + (ts->sequence / seq_divisor);
    
    ts->layer = layerVal;
    ts->column = columnVal;

    // If we got this far, everything must be ok...
    return kTRUE;
}
///________________________________________________________________________
 Bool_t LogID::fillIDFromGeom(LogID::TAG_STRUCT *ts) {
    // fill Pipeline, ADC Sequence, etc. from Geometry fields: 

    if (!isValidColumn(ts->column))
        return kFALSE;
    if (ts->layer & ~CAL_M_LAYER)
        return kFALSE;
    if (ts->tower & ~CAL_M_TOWER)
        return kFALSE;

    // Calculate XY, PIPELINE, ADC SEQUENCE from layer and column...
    UInt_t xyVal = ts->layer & CAL_M_XY;
    UInt_t pipeVal = ts->column / ((BOUNDS_COLUMN + 1) / (BOUNDS_PIPE + 1));
    UInt_t seqVal = (ts->column % 2) * (1 << (CAL_K_SEQ - 1)) + 
                    (ts->layer >> CAL_K_XY);

    ts->xy = xyVal;
    ts->pipeline = pipeVal;
    ts->sequence = seqVal;

    // If we got this far, everything must be ok...
    return kTRUE;
}
///________________________________________________________________________
 Bool_t LogID::isValidTagStruct(TAG_STRUCT ts) {
    // Test the validity of a particular tag structure.
    // Ensures that fields which don't use all possible values are
    // within bounds.  Compares 'geometric' and 'electronic' position data
    // and ensure that they are equivalent.

    // Test fields that don't use all possible values for correct range...
    if ((!isValidColumn(ts.column))     ||
        (!isValidPipeLine(ts.pipeline))
       )
        return kFALSE;
    
    // Calculate the column and layer from the Pipeline, Sequence and XY
    // fields.  Then compare...

    // seq_divisor is 1/2 the number of possible sequence values:
    UInt_t seq_divisor = 1 << (CAL_K_SEQ - 1);

    UInt_t layerVal = ((ts.sequence % seq_divisor) << CAL_K_XY) | ts.xy;
    if (layerVal != ts.layer) 
        return kFALSE;

    UInt_t columnVal = ts.pipeline * 2 + (ts.sequence / seq_divisor);
    if (columnVal != ts.column)
        return kFALSE;

    // If we got this far, everything must be ok...
    return kTRUE;
}
///________________________________________________________________________
 Bool_t LogID::isValidTagWord(UInt_t tagWord) {
    // In this function, we must ensure that the (Pipeline, Sequence, XY)
    // and (Layer, Column) data map to identical logs.  If this is not the
    // case, then the data encoded in the tagword is contradictory and 
    // should not be used.  This function also tests fields to ensure that 
    // values are within valid range.  It is important that this function 
    // is called on all tag words before they are stored or used!
    
    TAG_STRUCT ts;
    fillTagStruct(tagWord, &ts);
    
    return isValidTagStruct(ts);
}
///________________________________________________________________________
///
/// ACCESS FUNCTIONS for tagword fields:
///________________________________________________________________________
 UInt_t LogID::getTower(UInt_t tagWord) {
    // Returns the GLAST tower this log belongs to.  In the '99/2000
    // beamtest, this value is always 0.

    return static_cast<UInt_t>((tagWord >> CAL_V_TOWER) & CAL_M_TOWER);
}
///________________________________________________________________________
 UInt_t LogID::getColumn(UInt_t tagWord) {
    // Returns the column of the log in the calorimeter
    // Columns are numberd 0-9.  Looking at the positive X face of the cal
    // the log ends are numbered 0-9 from left to right.  Looking at the 
    // Positive Y face of the cal, the log ends are numbered 0-9 from right
    // to left.

    return static_cast<UInt_t>((tagWord >> CAL_V_COLUMN) & CAL_M_COLUMN);
}
///________________________________________________________________________
 UInt_t LogID::getLayer(UInt_t tagWord) {
    // Returns the layer this log is in.  Layers are numbered from
    // 0: (closest to TKR) to 7: (furthest from TKR).

    UInt_t layerVal = (tagWord >> CAL_V_LAYER) & CAL_M_LAYER;
    layerVal <<= CAL_K_XY;
    layerVal |= getXY(tagWord);

    return layerVal;
}
///________________________________________________________________________
 UInt_t LogID::getID(UInt_t tagWord) {
    // Returns the id of this log.  Each log in the calorimeter has a unique
    // id value based upon it's position in the cal.
    
    return static_cast<UInt_t>((tagWord >> CAL_V_ID) & CAL_M_ID);
}
///________________________________________________________________________
 UInt_t LogID::getPipeline(UInt_t tagWord) {
    // Returns the electronics pipeline the log is read out through

    return static_cast<UInt_t>((tagWord >> CAL_V_PIPE) & CAL_M_PIPE);
}
///________________________________________________________________________
 UInt_t LogID::getSequence(UInt_t tagWord) {
    // Returns the electronics ADC sequence the log is read out from

    return static_cast<UInt_t>((tagWord >> CAL_V_SEQ) & CAL_M_SEQ);
}
///________________________________________________________________________
 UInt_t LogID::getXY(UInt_t tagWord) {
    // Returns whether the log is in an x or y plane of the cal.
    
    return static_cast<UInt_t>((tagWord >> CAL_V_XY) & CAL_M_XY);
}
///________________________________________________________________________
// Fill a TAG_STRUCT with data from tagVal.
// *** NOTE: There is no assertion that user supplied tagword contains
// valid fields!
 void LogID::fillTagStruct(UInt_t tagVal, LogID::TAG_STRUCT *ts) {
    ts->column = getColumn(tagVal);
    ts->layer = getLayer(tagVal);
    ts->pipeline = getPipeline(tagVal);
    ts->sequence = getSequence(tagVal);
    ts->tower = getTower(tagVal);
    ts->xy = getXY(tagVal);
}
///________________________________________________________________________
// Fill a tagword from a tag structure:
// *** NOTE: There is no assertion that user supplied tag struct contains
// valid fields!
 UInt_t LogID::fillTagWord(LogID::TAG_STRUCT *ts) {
    UInt_t tagWord = 0;
    tagWord += (ts->xy & CAL_M_XY) << CAL_V_XY;
    tagWord += (ts->sequence & CAL_M_SEQ) << CAL_V_SEQ;
    tagWord += (ts->pipeline & CAL_M_PIPE) << CAL_V_PIPE;
    // When setting layer bits, shed common XY bit from layer value...
    tagWord += ((ts->layer >> CAL_K_XY) & CAL_M_LAYER) << CAL_V_LAYER;
    tagWord += (ts->column & CAL_M_COLUMN) << CAL_V_COLUMN;
    tagWord += (ts->tower & CAL_M_TOWER) << CAL_V_TOWER;

    return tagWord;
}
///________________________________________________________________________
 Bool_t LogID::setTag(UInt_t tagVal) { 
    // Set value of tag word to tagVal if taVal is valid

    if (isValidTagWord(tagVal)) {
        m_tag = tagVal;
        return kTRUE;
    }
    else return kFALSE;
}
///________________________________________________________________________
 Bool_t LogID::setTag(TAG_STRUCT *ts) {
    // Fill tag word from values in a tag struct.

    if (isValidTagStruct(*ts)) {
        m_tag = fillTagWord(ts);
        return kTRUE;
    }
    else return kFALSE;
}
///________________________________________________________________________
 UInt_t LogID::getColumn() const {
    // return column value from tag word:

    return getColumn(m_tag);
}
///_______________________________________________________________________
 Bool_t LogID::setColumn(UInt_t columnVal) {
    // Sets the column field in the tag word

    if (!isValidColumn(columnVal)) 
        return kFALSE;

    m_tag &= ~(CAL_M_COLUMN << CAL_V_COLUMN);
    m_tag |= columnVal << CAL_V_COLUMN;

    return kTRUE;
}
///________________________________________________________________________
 UInt_t LogID::getID() const {
    // Returns the unique id of this log

    return getID(m_tag);
}
///________________________________________________________________________
LogID::CALAxes LogID::getXY() const {
    // Returns whether this log is in an x (logs || x-axis) or y 
    // (logs || y-axis) layer

    return (CALAxes)getXY(m_tag);
}
///_______________________________________________________________________
 Bool_t LogID::setXY(CALAxes xyVal) {
    // Sets the XY field in the tag word
    
    m_tag &= ~(CAL_M_XY << CAL_V_XY);
    m_tag |= xyVal << CAL_V_XY;

    return kTRUE;
}
///________________________________________________________________________
 UInt_t LogID::getLayer() const {
    // return layer value from tag word:

    return getLayer(m_tag);
}
///________________________________________________________________________
 UInt_t LogID::getPipeline() const {
    // return layer value from tag word:

    return getPipeline(m_tag);
}
///________________________________________________________________________
 UInt_t LogID::getSequence() const {
    // return ADC sequence value from tag word:

    return getSequence(m_tag);
}
///________________________________________________________________________
 Bool_t LogID::setLayer(UInt_t layerVal) {
    // Sets the layer field in the tag word

    // *** See note in header (in the private enum of tagword fields) 
    // *** as to why the following is done:
    // Strip off LSB, as it goes in the XY field...
    UInt_t xyVal = (layerVal & CAL_M_XY) << CAL_V_XY;
    // Now get the layer value minus the XY bit...
    UInt_t lVal = (layerVal >> CAL_V_XY);

    // Check if the remaining bits represent a valid layer value:
    if (lVal & CAL_M_LAYER)
        return kFALSE;

    // Set LAYER and XY fields...
    m_tag &= ~(CAL_M_LAYER << CAL_V_LAYER);
    m_tag |= lVal << CAL_V_LAYER;
    m_tag &= ~(CAL_M_XY << CAL_V_XY);
    m_tag |= xyVal << CAL_V_XY;

    return kTRUE;
}
///________________________________________________________________________
/*
Bool_t LogID::setID(UInt_t idVal) {
    if (!isValidID(idVal))
        return kFALSE;
    



    return kTRUE;
}
*/
///________________________________________________________________________


ROOT page - Class index - Top of the page

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.