cf2rr.cc File Reference

#include <fstream>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <math.h>
#include <float.h>
#include <stdint.h>
#include <glob.h>
#include <unistd.h>
#include <getopt.h>
#include <time.h>
#include <sys/time.h>
#include <ctime>
#include "BeamData/bdcf/ifzstream.h"
#include "BeamData/python/bdp/BeamData.h"
#include "BeamData/python/bdp/BeamData.cc"
#include "OnlineUtil/rototalk.h"
#include <algorithm>
#include <set>
#include <map>
#include "TTimeStamp.h"
#include "TStopwatch.h"
#include "TSystem.h"

Go to the source code of this file.

Classes

struct  CompareDesc< T >
struct  CompareAsc< T >
class  cfCfg
class  cfDeviceData
class  cfEventData
class  cfProcessor

Namespaces

namespace  TMath

Typedefs

typedef struct timespec timespec_t
typedef struct tm tm_t
typedef long long int msTimeStamp_t
typedef std::pair< int32_t,
int32_t > 
nanoTSPair_t
typedef std::pair< int32_t,
int32_t > 
milliTSPair_t

Enumerations

enum  cf2rr_err {
  cf2rr_success = 0, cf2rr_dd_toofewfields = 101, cf2rr_dd_badtime = 102, cf2rr_dd_badvalue = 103,
  cf2rr_ed_badevent = 104, cf2rr_nosuchfile = 105, cf2rr_firstlinenotevt = 106, cf2rr_last_of_errors
}

Functions

template<typename Element , typename Index >
void TMath::Sort (Index n, const Element *a, Index *index, bool down=true)
template<typename Iterator , typename IndexIterator >
void TMath::SortItr (Iterator first, Iterator last, IndexIterator index, bool down=true)
msTimeStamp_t ParseTimeString (const char *)
std::string UTCTimeString (msTimeStamp_t)
std::string LocalTimeString (msTimeStamp_t)
std::vector< std::string > UniqueNames (std::vector< std::string >, int verbose)
std::vector< std::string > TokenizeString (std::string values, std::string sepchar, bool allowempty=true, bool verbose=false)
std::string Basename (std::string path)
bool AreDoublesSame (double a, double b)
nanoTSPair_t TimeStamp2SecNano (msTimeStamp_t tsms)
milliTSPair_t TimeStamp2SecMilli (msTimeStamp_t tsms)
void DoubleToSecMSec (double t, int32_t &sec, int32_t &msec)
int main (int argc, char **argv)
bool IsLeapYear (int year)
time_t MktimeFromUTC (tm_t *tmstruct)
void DumpTMStruct (const tm_t &tmstruct)

Variables

const char * exename = "cf2rr"

Typedef Documentation

typedef std::pair<int32_t,int32_t> milliTSPair_t

Definition at line 53 of file cf2rr.cc.

typedef long long int msTimeStamp_t

Definition at line 51 of file cf2rr.cc.

typedef std::pair<int32_t,int32_t> nanoTSPair_t

Definition at line 52 of file cf2rr.cc.

typedef struct timespec timespec_t

Definition at line 33 of file cf2rr.cc.

typedef struct tm tm_t

Definition at line 34 of file cf2rr.cc.


Enumeration Type Documentation

enum cf2rr_err
Enumerator:
cf2rr_success 
cf2rr_dd_toofewfields 
cf2rr_dd_badtime 
cf2rr_dd_badvalue 
cf2rr_ed_badevent 
cf2rr_nosuchfile 
cf2rr_firstlinenotevt 
cf2rr_last_of_errors 

Definition at line 57 of file cf2rr.cc.

00057                {
00058   cf2rr_success = 0,
00059   cf2rr_dd_toofewfields = 101,
00060   cf2rr_dd_badtime      = 102,
00061   cf2rr_dd_badvalue     = 103,
00062   cf2rr_ed_badevent     = 104,
00063   cf2rr_nosuchfile      = 105,
00064   cf2rr_firstlinenotevt = 106,
00065   cf2rr_last_of_errors
00066 };


Function Documentation

bool AreDoublesSame ( double  a,
double  b 
)

Definition at line 1742 of file cf2rr.cc.

Referenced by cfDeviceData::IsSame(), and MCFilePOTInfo::IsSameAll().

01742                                         {
01743   // For float or double, need to determine equality while 
01744   // accounting for some degree of imprecision
01745   // The method applied here is adopted from Theodore C. Belding's
01746   // fcmp implementation of Donald Knuth's algorithm. 
01747   double value[2] = {a,b};
01748   double epsilon = 10.*FLT_EPSILON;
01749   //      if ( isDouble[0] || isDouble[1] ) epsilon = DBL_EPSILON;
01750   int exponent;
01751   frexp(fabs(value[0]) > fabs(value[1]) ? value[0] : value[1], &exponent);
01752   double delta = ldexp(epsilon,exponent);
01753   double difference = value[0] - value[1];
01754   if ( difference > delta || difference < -delta ) {
01755     return false;
01756   }
01757   return true;
01758 }

std::string Basename ( std::string  path  ) 

Definition at line 1732 of file cf2rr.cc.

References len.

Referenced by cfEventData::cfEventData().

01732                                    {
01733   size_t len = path.size();
01734   size_t slash = path.find_last_of("/");
01735   if ( slash+1 >= len-1 ) return "";
01736   return path.substr(slash+1,std::string::npos);
01737 }

void DoubleToSecMSec ( double  t,
int32_t &  sec,
int32_t &  msec 
) [inline]

Definition at line 186 of file cf2rr.cc.

Referenced by ifbProcRoto::SpillDevice().

00187 {
00188   sec = (int32_t)t;  msec = (int32_t)((t - (int32_t)(sec))*1.0e3);
00189 }

void DumpTMStruct ( const tm_t tmstruct  ) 

Definition at line 1857 of file cf2rr.cc.

01858 {
01859    // Print out the "tm" structure:
01860    // tmstruct.tm_year = year;    // years since 1900
01861    // tmstruct.tm_mon  = month-1; // months since Jan [0,11]
01862    // tmstruct.tm_mday = day;     // day of the month [1,31]
01863    // tmstruct.tm_hour = hour;    // hours since midnight [0,23]
01864    // tmstruct.tm_min  = min;     // minutes after the hour [0,59]
01865    // tmstruct.tm_sec  = sec;     // seconds after the minute [0,59]
01866    // tmstruct.tm_wday            // day of week [0,6]
01867    // tmstruct.tm_yday            // days in year [0,365]
01868    // tmstruct.tm_isdst           // DST [-1/0/1]  (unknown,false,true)
01869 
01870    printf(" tm { year %4d, mon   %2d, day   %2d,\n",
01871           tmstruct.tm_year,
01872           tmstruct.tm_mon,
01873           tmstruct.tm_mday);
01874    printf("      hour   %2d, min   %2d, sec   %2d,\n",
01875           tmstruct.tm_hour,
01876           tmstruct.tm_min,
01877           tmstruct.tm_sec);
01878    printf("      wday   %2d, yday %3d, isdst %2d",
01879           tmstruct.tm_wday,
01880           tmstruct.tm_yday,
01881           tmstruct.tm_isdst);
01882 #ifdef linux
01883 //#ifdef __GNUC__
01884 // special GCC extras
01885    printf(",\n      tm_gmtoff %7ld,  tm_zone \"%s\"",
01886 #ifdef __USE_BSD
01887           tmstruct.tm_gmtoff,tmstruct.tm_zone);
01888 #else
01889           tmstruct.__tm_gmtoff,tmstruct.__tm_zone);
01890 #endif
01891 #endif
01892    printf("}\n");
01893 }

bool IsLeapYear ( int  year  ) 

Definition at line 1765 of file cf2rr.cc.

Referenced by MktimeFromUTC().

01766 {
01767    // Is the given year a leap year.
01768 
01769 
01770    // The calendar year is 365 days long, unless the year is exactly divisible
01771    // by 4, in which case an extra day is added to February to make the year
01772    // 366 days long. If the year is the last year of a century, eg. 1700, 1800,
01773    // 1900, 2000, then it is only a leap year if it is exactly divisible by
01774    // 400. Therefore, 1900 wasn't a leap year but 2000 was. The reason for
01775    // these rules is to bring the average length of the calendar year into
01776    // line with the length of the Earth's orbit around the Sun, so that the
01777    // seasons always occur during the same months each year.
01778 
01779    if (year%4 != 0) {
01780       return false;
01781    }
01782    else {
01783       if (year%400 == 0) {
01784          return true;
01785       }
01786       else { 
01787          if (year%100 == 0) {
01788             return false;
01789          }
01790          else {
01791             return true;
01792          }
01793       }
01794    }
01795 
01796 }

std::string LocalTimeString ( msTimeStamp_t  ts  ) 

Definition at line 1988 of file cf2rr.cc.

Referenced by cfCfg::PrintConfig(), ifbConfig::PrintConfig(), and cfProcessor::PrintStatistics().

01989 {
01990   char bufferloc[80];
01991   time_t loctime = (time_t)(ts/1000);
01992   struct tm * timeinfoloc = localtime( &loctime );
01993   strftime (bufferloc,80,"%F %T (local)",timeinfoloc);
01994   return std::string( bufferloc );
01995 }

int main ( int  argc,
char **  argv 
)

Definition at line 362 of file cf2rr.cc.

References cfProcessor::CheckPointReport(), exename, exit(), cfProcessor::ExpandFileList(), cfProcessor::MergeAdjacent(), cfCfg::ParseArgv(), cfCfg::PrintAndQuit, cfCfg::PrintConfig(), cfProcessor::PrintStatistics(), cfProcessor::ReadFiles(), cfCfg::Reread, cfProcessor::SendToRotorooter(), and cfCfg::Verbose.

00363 {
00364   exename = argv[0];
00365   //
00366   // Get configuration options
00367   //
00368   cfCfg cfg;
00369   cfg.ParseArgv(argc,argv);
00370   if ( cfg.PrintAndQuit || cfg.Verbose > 0  ) cfg.PrintConfig();
00371   if ( cfg.PrintAndQuit ) exit(0);
00372 
00373   cfProcessor cfp(cfg);
00374 
00375   cfp.CheckPointReport("start cfProcessor");
00376 
00377   cfp.ExpandFileList();
00378 
00379   cfp.CheckPointReport("after ExpandFileList");
00380 
00381   // simulate lots of files
00382   int32_t ntimes = cfg.Reread;
00383   if ( ntimes < 1 ) ntimes = 1;
00384   for (int32_t i=0; i < ntimes; ++i) {
00385     cfp.ReadFiles();
00386   }
00387   cfp.CheckPointReport("done all ReadFiles");
00388 
00389   cfp.MergeAdjacent();
00390   cfp.CheckPointReport("post MergeAdjacent");
00391 
00392   cfp.PrintStatistics();
00393   int status = cfp.SendToRotorooter();
00394 
00395   exit(status);
00396 
00397 } // end of main() program

time_t MktimeFromUTC ( tm_t tmstruct  ) 

Definition at line 1799 of file cf2rr.cc.

References IsLeapYear(), and Munits::year.

Referenced by ParseTimeString().

01800 {
01801    // Equivalent of standard routine "mktime" but
01802    // using the assumption that tm struct is filled with UTC, not local, time.
01803 
01804    // This version *ISN'T* configured to handle every possible
01805    // weirdness of out-of-range values in the case of normalizing
01806    // the tm struct.
01807 
01808    // This version *DOESN'T* correctly handle values that can't be
01809    // fit into a time_t (i.e. beyond year 2038-01-18 19:14:07, or
01810    // before the start of Epoch).
01811 
01812    const int days[]     = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
01813    const int daysLeap[] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
01814 
01815    int year = tmstruct->tm_year + 1900;
01816    bool isleap = IsLeapYear(year);
01817 
01818    const int *daysInMonth = days;
01819    if (isleap) daysInMonth = daysLeap;
01820 
01821    // fill in tmstruct->tm_yday
01822 
01823    int &ref_tm_mon = tmstruct->tm_mon;
01824    int &ref_tm_mday = tmstruct->tm_mday;
01825    // count days in months past
01826    tmstruct->tm_yday = 0;
01827    for (int imonth = 0; imonth < ref_tm_mon; imonth++) {
01828       tmstruct->tm_yday += daysInMonth[imonth];
01829    }
01830    tmstruct->tm_yday += ref_tm_mday - 1;  // day [1-31] but yday [0-365]
01831 
01832    // adjust if day in this month is more than the month has
01833    while (ref_tm_mday > daysInMonth[ref_tm_mon]) {
01834       ref_tm_mday -= daysInMonth[ref_tm_mon];
01835       ref_tm_mon++;
01836    }
01837 
01838    // *should* calculate tm_wday (0-6) here ...
01839 
01840    // UTC is never DST
01841    tmstruct->tm_isdst = 0;
01842 
01843    // Calculate seconds since the Epoch based on formula in
01844    // POSIX  IEEEE Std 1003.1b-1993 pg 22
01845 
01846    int utc_sec = tmstruct->tm_sec +
01847                  tmstruct->tm_min*60 +
01848                  tmstruct->tm_hour*3600 +
01849                  tmstruct->tm_yday*86400 +
01850                  (tmstruct->tm_year-70)*31536000 +
01851                  ((tmstruct->tm_year-69)/4)*86400;
01852 
01853    return utc_sec;
01854 }

double ParseTimeString ( const char *  s  ) 

Definition at line 1896 of file cf2rr.cc.

References Munits::day, Munits::hour, min, MktimeFromUTC(), month, and Munits::year.

Referenced by ifbConfig::ParseArgv(), and cfCfg::ParseArgv().

01897 {
01898    // assume string of the form 'YYYY-MM-DD hh:mm:ss[.nnnnn]'
01899    bool isUTC = true;
01900 
01901    int year=0, month=0, day=0;
01902    int hour=0, min=0, sec=0;
01903    float fltsec=0, frac_sec;
01904    char buff[128] = {0};
01905 
01906    int nitems = sscanf(s,"%d-%d-%d %d:%d:%f%s",
01907                        &year,&month,&day,&hour,&min,&fltsec,buff);
01908    //std::cout << "rest of time string \"" << buff << "\"" << std::endl;
01909    //std::cout << " YY " << year << " MM " << month << " DD " << day
01910    //          << " hh " << hour << " mm " << min << " sec " << fltsec
01911    //          << std::endl;
01912 
01913    if ( nitems != 6 && nitems != 7 ) {
01914      std::cout << "ParseTimeString got " << nitems << " items" 
01915                << std::endl;
01916    }
01917    // possibility of fractional seconds
01918    sec = (int)fltsec;
01919    frac_sec = ( fltsec - sec );
01920 
01921    // check trailing text
01922    // if anything but "", "Z", "UTC" or "GMT" assume time given was
01923    // in local time ... don't try to parse it as a TZ ...
01924    std::string tzstr(buff);
01925    // trim lead/trailing blanks
01926    if( tzstr.find_first_not_of(" ()[]{}\n") != 0)
01927      tzstr.erase( 0,  tzstr.find_first_not_of(" ()[]{}\n")  );
01928    if( tzstr.find_last_not_of(" ()[]{}\n") != tzstr.length() )
01929      tzstr.erase( tzstr.find_last_not_of(" ()[]{}\n")+1, tzstr.length() );
01930 
01931    isUTC = ( tzstr == ""    || 
01932              tzstr == "Z"   || tzstr == "z" ||
01933              tzstr == "UTC" || tzstr == "GMT" );
01934    //std::cout << " isUTC " << isUTC << " tzstr \"" << tzstr << "\"" 
01935    //          << " c[0] " << (int)(tzstr[0]) << std::endl;
01936 
01937    // month & day both use normal 1..12 and 1..31 counting
01938    // hours, min, sec run from 0 to 23, 59, 59 respectively;
01939    // secOffset provides method for adjusting for alternative timezones
01940    //
01941    // "year"  |    0    1 ... 37 | 38...69   |   70 .. 100  101 ..  137
01942    // true    | 2000 2001   2037 | undefined | 1970   2000 2001 .. 2037
01943    //
01944    // "year"  | 138...1969 | 1970 .. 2037 | ...
01945    // true    | undefined  | 1970 .. 2037 | undefined 
01946    //
01947 
01948    // deal with special formats of year
01949    if (year <= 37)                year += 2000;
01950    if (year >= 70 && year <= 137) year += 1900;
01951    // tm.tm_year is years since 1900
01952    if (year >= 1900)              year -= 1900;
01953 
01954    struct tm tmstruct;
01955    tmstruct.tm_year  = year;    // years since 1900
01956    tmstruct.tm_mon   = month-1; // months since Jan [0,11]
01957    tmstruct.tm_mday  = day;     // day of the month [1,31]
01958    tmstruct.tm_hour  = hour;    // hours since midnight [0,23]
01959    tmstruct.tm_min   = min;     // minutes after the hour [0,59]
01960    tmstruct.tm_sec   = sec;     // seconds after the minute [0,59]     
01961    tmstruct.tm_isdst = -1;      // let "mktime" determine DST setting
01962 
01963    //const time_t bad_time_t = (time_t) -1;
01964    // convert tm struct to time_t, if values are given in UTC then
01965    // no standard routine exists and we'll have to use our homegrown routine,
01966    // if values are given in local time then use "mktime"
01967    // which also normalizes the tm struct as a byproduct
01968    time_t utc_sec = (isUTC) ? MktimeFromUTC(&tmstruct) : mktime(&tmstruct);
01969 
01970    msTimeStamp_t atime = utc_sec;
01971    atime *= 1000;  // careful about multiply by 1000 after long->longlong
01972    atime += (int)(frac_sec*1000);
01973    //std::cout << " msTimeStamp " << atime 
01974    //          << " utc_sec     " << utc_sec 
01975    //          << " sizeof " << sizeof(msTimeStamp_t) << std::endl;
01976    return atime;
01977 }

milliTSPair_t TimeStamp2SecMilli ( msTimeStamp_t  tsms  ) 

Definition at line 179 of file cf2rr.cc.

Referenced by cfProcessor::SendToRotorooter().

00179                                                      {
00180   // ms timestamp into sec + milli
00181   milliTSPair_t parts;
00182   parts.first  = (int32_t)(tsms/1000);
00183   parts.second = (tsms - 1000*parts.first);
00184   return parts;
00185 }

nanoTSPair_t TimeStamp2SecNano ( msTimeStamp_t  tsms  ) 

Definition at line 172 of file cf2rr.cc.

Referenced by cfProcessor::SendToRotorooter().

00172                                                    {
00173   // ms timestamp into sec + nano
00174   nanoTSPair_t parts;
00175   parts.first  = (int32_t)(tsms/1000);
00176   parts.second = (tsms - 1000*parts.first)*1000000;
00177   return parts;
00178 }

std::vector< std::string > TokenizeString ( std::string  values,
std::string  sepchar,
bool  allowempty = true,
bool  verbose = false 
)

Definition at line 1696 of file cf2rr.cc.

Referenced by cfProcessor::GuessEventLabel(), cfCfg::ParseArgv(), cfProcessor::ReadOneFile(), and cfEventData::Unpack().

01700 {
01701   // Separate "values" string into elements under the assumption
01702   // that they are separated by any of the characters in "spechar".
01703 
01704   std::vector<std::string> rlist;
01705 
01706   if ( verbose ) {
01707     std::cout << "TokenizeString \"" << values 
01708               << "\" separated by \"" << sepchar << "\"" << std::endl;
01709   }
01710 
01711   size_t pos_beg = 0;
01712   size_t str_end = values.size();
01713   while ( pos_beg != string::npos && pos_beg < str_end ) {
01714     size_t pos_end = values.find_first_of(sepchar.c_str(),pos_beg);
01715     std::string onevalue = values.substr(pos_beg,pos_end-pos_beg);
01716     if ( verbose ) {
01717       std::cout << "  [" << std::setw(2) << rlist.size() 
01718                 << "] \"" << onevalue  << "\" at [" 
01719                 << pos_beg << "," << pos_end << ")"<< std::endl;
01720     }
01721     pos_beg = pos_end+1;
01722     if ( pos_end == string::npos ) pos_beg = str_end;
01723     if ( allowempty || onevalue != "" ) {
01724       rlist.push_back(onevalue);
01725     }
01726   }
01727   if ( verbose ) std::cout << std::endl;
01728 
01729   return rlist;
01730 }

std::vector< std::string > UniqueNames ( std::vector< std::string >  names,
int  verbose 
)

Definition at line 1661 of file cf2rr.cc.

References exename.

Referenced by ifbProcBase::NewCache().

01663 {
01664   //
01665   // Weed out duplicate names (also print out duplicates)
01666   //
01667   std::map<std::string,int> namecnt;
01668   for ( size_t iname = 0; iname < names.size(); ++iname ) {
01669     namecnt[names[iname]]++;
01670   }
01671   if ( names.size() != namecnt.size() ) {
01672     if ( verbose > 3 ) {
01673       std::cout << exename << ": bfp.GetDeviceList() returned " 
01674                 << names.size() << " devices, " 
01675                 << namecnt.size() << " unique"
01676                 << std::endl;
01677     }
01678     // clear old list
01679     names.clear();
01680     // build new list from sorted map
01681     std::map<std::string,int>::const_iterator ncitr = namecnt.begin();
01682     for ( ; ncitr != namecnt.end(); ++ncitr ) {
01683       names.push_back(ncitr->first);
01684       int cnt = ncitr->second;
01685       if ( cnt > 1 && verbose > 4 ) {
01686         std::cout << "  " << std::left << std::setw(12) 
01687                   << ncitr->first << std::right
01688                   << " was in device list " << cnt 
01689                   << " times." << std::endl;
01690       }
01691     }
01692   }
01693   return names;
01694 }

std::string UTCTimeString ( msTimeStamp_t  ts  ) 

Definition at line 1979 of file cf2rr.cc.

Referenced by cfCfg::PrintConfig(), ifbConfig::PrintConfig(), cfProcessor::PrintStatistics(), ifbProcBase::ScanWindow(), and cfEventData::Unpack().

01980 {
01981   char buffergmt[80];
01982   time_t gmttime = (time_t)(ts/1000);
01983   struct tm * timeinfogmt = gmtime( &gmttime );
01984   strftime (buffergmt,80,"%F %T (UTC)",timeinfogmt);
01985   return std::string( buffergmt );
01986 }


Variable Documentation

const char* exename = "cf2rr"

Generated on 19 Jan 2018 for loon by  doxygen 1.6.1