#pragma implementation

// -----------------------------------------------------------------------------

#include <Rtypes.h>
#include "TString.h"
#include <stdio.h>
#include "hsuprogress.h"

// -----------------------------------------------------------------------------
//*-- Author : Marcin Jaskula
// -----------------------------------------------------------------------------

ClassImp(HSUProgress)

// -----------------------------------------------------------------------------

static const Char_t* g_pctHSUProgressConst[] = { ".oOo", "-\\|/" };

//______________________________________________________________________________
// A progress bar class.
// It gives a simple interface for showing a progress bar of some Long_t task
// as well as it may estimate the time left to the end of the job.
// A typical output of the progress bar looks like:
//
// ##########  10 % done in     1.85 s; ~    16.65 s left;    540.54 evts/s
// ##########  20 % done in     3.65 s; ~    14.60 s left;    547.95 evts/s
// ##########  30 % done in     5.42 s; ~    12.65 s left;    553.51 evts/s
// ##########  40 % done in     7.21 s; ~    10.82 s left;    554.79 evts/s
// ##########  50 % done in     9.08 s; ~     9.08 s left;    550.66 evts/s
// ####-
// ....
//
// 10000 events done in    18.05 s;   554.02 evts/s
//
// All parameters of the display are configurable:
//
// Progress bars on the left: ("#####" in the example)
// - turn it on/off with SetProgressOn method (default on)
// - how often a new character in the bar appears may be set by:
//     - SetProgressPer
//     - SetProgressEvents
//     methods. Default: each 1% of the max events
// - the character in the bar may be changed by GetProgressChar method (def. #)
//
// Spinning character: ("-" in the example)
// - turn it on/off with SetSpinOn method (default on)
// - how often it spins may be changed by:
//     - SetSpinPer
//     - SetSpinEvents
//     methods. Default: 0.1%
// - characters which define a spin may be set by methods:
//     - SetSpinChars(Int_t iType)
//          iType = 0: ".oOo"
//                = 1: "-\\|/"
//     - SetSpinChars(const Char_t *pStr) - sets user define string
//          e.g. SetSpinChars("Hades is fine")
//
// Timing information: ("10% done ..." in the example)
// - turn in on/off with SetTimerOn method (default on)
// - how often it appears may be changed by:
//     - SetTimerPer
//     - SetProgressEvents
//     methods. Default: 10%
//
// Information about full time of the loop: (the last line)
// - turn it on/off with SetFullTimerOn method (default on)
//
//
// If the counter overflows the maximum value defined in the constructor
// a warning is reported for the first time.
//

HSUProgress::HSUProgress(Int_t iMax)
{
// Constructor in which a maximum number of steps may be set.
// The default value of iMax = 100
    Reset();
    m_iMax = iMax;
}

// -----------------------------------------------------------------------------

void HSUProgress::Reset()
{
// Reset all parameters to the default values
    m_iMax           = 100;
    m_iLast          = -1;

    m_bSpin          = kTRUE;
    m_bSpinInPer     = kFALSE;
    m_fSpinSet       = 0.1f;
    m_fSpinReal      = 0.0f;
    m_psSpinChars    = g_pctHSUProgressConst[0];
    m_iSpinLen       = strlen(m_psSpinChars);

    m_bProgress      = kTRUE;
    m_bProgressInPer = kTRUE;
    m_fProgressSet   = 1.0f;
    m_fProgressReal  = 0.0f;
    m_cProgressChar  = '#';

    m_bTimer         = kTRUE;
    m_bTimerInPer    = kTRUE;
    m_fTimerSet      = 10.0f;
    m_fTimerReal     = 0.0f;

    m_bFullTimer     = kTRUE;

    tTimer.Reset();

    m_bWasOutOfRange = kFALSE;
}

// -----------------------------------------------------------------------------

HSUProgress::~HSUProgress()
{
// An empty destructor
}

// -----------------------------------------------------------------------------

void HSUProgress::Restart(void)
{
// Reset the counter
    m_iLast = -1;
}

// -----------------------------------------------------------------------------

void HSUProgress::SetSpinPer(Float_t f)
{
// How often the spin changes - in per cent of the iMax
    m_bSpinInPer = kTRUE;
    m_fSpinSet = (f <= 0.0f) ? 0.01f : f;
}

// -----------------------------------------------------------------------------

void HSUProgress::SetSpinEvents(Int_t i)
{
// How often the spin changes - in events
    m_bSpinInPer = kFALSE;
    m_fSpinSet = (i <= 0) ? 1.0f : (Float_t)i;
}

// -----------------------------------------------------------------------------

void HSUProgress::SetSpinChars(const Char_t *pStr)
{
// Set the string of characters used by spin
    m_psSpinChars = pStr;
    m_iSpinLen    = strlen(m_psSpinChars);
}

// -----------------------------------------------------------------------------

void HSUProgress::SetSpinChars(Int_t iType)
{
// Set the string of characters used by spin from two defaults:
// 0 - ".oOo"
// 1 - "-\\|/"
    if((iType >= 0) && (iType < (Int_t)sizeof(g_pctHSUProgressConst)))
        m_psSpinChars = g_pctHSUProgressConst[iType];

    m_iSpinLen = strlen(m_psSpinChars);
}

// -----------------------------------------------------------------------------

Float_t HSUProgress::GetSpinReal(void)
{
// How often (in events) spin changes
    m_fSpinReal = (m_bSpinInPer)
                    ? m_fSpinSet : (100.0f * m_fSpinSet / m_iMax);

    return m_fSpinReal;
}

// -----------------------------------------------------------------------------

void HSUProgress::SetProgressPer(Float_t f)
{
// How often the progress bar changes - in per cent
    m_bProgressInPer = kTRUE;
    m_fProgressSet = (f <= 0.0f) ? 0.01f : f;
}

// -----------------------------------------------------------------------------

void HSUProgress::SetProgressEvents(Int_t i)
{
// How often the progress bar changes - in events
    m_bProgressInPer = kFALSE;
    m_fProgressSet = (i <= 0) ? 1.0f : (Float_t)i;
}

// -----------------------------------------------------------------------------

Float_t HSUProgress::GetProgressReal(void)
{
// How often (in events) progress bar changes
    m_fProgressReal = (m_bProgressInPer)
                    ? m_fProgressSet : (100.0f * m_fProgressSet / m_iMax);

    return m_fProgressReal;
}

// -----------------------------------------------------------------------------

void HSUProgress::SetTimerPer(Float_t f)
{
// How often the timer info appears - in per cent
    m_bTimerInPer = kTRUE;
    m_fTimerSet = (f <= 0.0f) ? 0.01f : f;
}

// -----------------------------------------------------------------------------

void HSUProgress::SetTimerEvents(Int_t i)
{
// How often the timer info appears - in events
    m_bTimerInPer = kFALSE;
    m_fTimerSet = (i <= 0) ? 1.0f : (Float_t)i;
}

// -----------------------------------------------------------------------------

Float_t HSUProgress::GetTimerReal(void)
{
// How often (in events) the timer info appears
    m_fTimerReal = (m_bTimerInPer)
                    ? m_fTimerSet : (100.0f * m_fTimerSet / m_iMax);

    return m_fTimerReal;
}

// -----------------------------------------------------------------------------

void HSUProgress::Next(Int_t iSteps)
{
// Execute the progress for the next step
// Default iSteps = 1
Float_t fPrev;
Float_t fCur;
Int_t   iChangeSpin     = 0;
Bool_t  bChangeSpin     = kFALSE;
Int_t   iChangeProgress = 0;
Bool_t  bChangeTimer    = kFALSE;
Int_t   i;

    if(m_iMax <= 0)
    {
        if( ! m_bSpin)
            return;

        if(m_iLast < 0)
        {
            fPrev = 0.0;
            m_iLast = iSteps;
            m_fTimerReal = ((m_bTimerInPer) || (m_fTimerSet <= 0))
                                ? 10 : m_fTimerSet;
        }
        else
        {
            fPrev    = m_iLast / m_fTimerReal;
            m_iLast += iSteps;
        }

        fCur = m_iLast / m_fTimerReal;

        if(Int_t(fCur) != Int_t(fPrev))
        {
            iChangeSpin = Int_t(fCur);
            bChangeSpin = kTRUE;
        }
    }
    else
    {
        if(m_iLast >= m_iMax)
        {
            if( ! m_bWasOutOfRange)
            {
                printf("\nProgress out of range: %d / %d\n", m_iLast, m_iMax);
                m_bWasOutOfRange = kTRUE;
            }

            m_iLast += iSteps;

            return;
        }

        if(m_iLast < 0)
        {
            GetSpinReal();
            GetProgressReal();
            GetTimerReal();

            fPrev   = 0.0f;
            m_iLast = iSteps;
            fCur    = (100.0f * m_iLast) / m_iMax;
            bChangeSpin = m_bSpin;
            tTimer.Start(kTRUE);
        }
        else
        {
            fPrev    = (100.0f * m_iLast) / m_iMax;
            m_iLast += iSteps;
            fCur     = (100.0f * m_iLast) / m_iMax;
        }

        if(m_bSpin)
        {
            iChangeSpin = (Int_t)(fCur / m_fSpinReal);
            if((Int_t)(fPrev / m_fSpinReal) != iChangeSpin)
                bChangeSpin = kTRUE;
        }

        if(m_bProgress)
        {
            iChangeProgress = (Int_t)(fCur / m_fProgressReal)
                                - (Int_t)(fPrev / m_fProgressReal);
        }

        if(m_bTimer)
        {
            if((Int_t)(fPrev / m_fTimerReal) != (Int_t)(fCur / m_fTimerReal))
                bChangeTimer = kTRUE;
        }
    }

    if((m_bSpin) && ((iChangeProgress > 0) || (bChangeTimer)))
        bChangeSpin = kTRUE;

        // clear spin
    if((bChangeSpin != 0) && (fPrev != 0.0f))
        printf("\b");

        // write progress
    for(i = 0; i < iChangeProgress; i++)
        printf("%c", m_cProgressChar);

        // write the timer info
    if(bChangeTimer)
    {
        printf(" %3d %% done in %8.2f s; ~ %8.2f s left;  %8.2f evts/s\n",
                (Int_t)fCur, tTimer.RealTime(),
                (100.0f - fCur) * tTimer.RealTime() / fCur,
                ((double)m_iLast / tTimer.RealTime()));

        tTimer.Continue();
    }

        // write the spin or the total time
    if((m_iMax <= 0) || (m_iLast < m_iMax))
    {
        if(bChangeSpin)
            printf("%c", m_psSpinChars[iChangeSpin % m_iSpinLen]);
    }
    else
    {
        if(m_bFullTimer)
            Final();
    }

    if((bChangeSpin) || (iChangeProgress > 0) || (bChangeTimer))
        fflush(stdout);
}

// -----------------------------------------------------------------------------

void HSUProgress::Final(void)
{
// Print the final line of the progress bar
    if(m_iLast <= m_iMax)
    {
        printf("\n%d events done in %8.2f s; %8.2f evts/s\n",
            m_iLast, tTimer.RealTime(), ((double)m_iLast / tTimer.RealTime()));
    }

    m_iLast = m_iMax + 1;
}

Last change: Sat May 22 13:13:04 2010
Last generated: 2010-05-22 13:13

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.