cfProcessor Class Reference

List of all members.

Public Member Functions

 cfProcessor (cfCfg cfgIn)
virtual ~cfProcessor ()
void ExpandFileList ()
void ReadFiles ()
void ReadOneFile (const std::string &fname)
void AdoptEvent (cfEventData *cfed)
void MergeAdjacent ()
int32_t SendToRotorooter ()
void PrintStatistics ()
std::string GuessEventLabel (const std::string &fname)
void CheckPointReport (std::string state)

Protected Attributes

cfCfg cfg
BeamData bd
std::map< msTimeStamp_t,
cfEventData * > 
edmap
std::map< std::string, size_t > devlist
std::map< std::string, size_t > triglist
std::map< std::string, size_t > faketriglist
std::map< int32_t, size_t > etints
std::map< int32_t, size_t > delays

Detailed Description

Definition at line 331 of file cf2rr.cc.


Constructor & Destructor Documentation

cfProcessor::cfProcessor ( cfCfg  cfgIn  )  [inline]

Definition at line 333 of file cf2rr.cc.

00333 : cfg(cfgIn) { ; }

cfProcessor::~cfProcessor (  )  [virtual]

Definition at line 1072 of file cf2rr.cc.

References edmap.

01072                           {
01073 
01074   // clean up
01075   std::map<msTimeStamp_t,cfEventData*>::reverse_iterator mitr = edmap.rbegin();
01076   for ( ; mitr != edmap.rend(); ++mitr ) {
01077     cfEventData* ed = mitr->second;
01078     mitr->second = 0;
01079     delete ed;
01080   }
01081 
01082 }


Member Function Documentation

void cfProcessor::AdoptEvent ( cfEventData cfed  ) 

Definition at line 1294 of file cf2rr.cc.

References cfg, cfEventData::Devices(), cfEventData::EarliestTime(), edmap, cfEventData::TimeStamp(), and cfCfg::Verbose.

Referenced by ReadOneFile().

01294                                               {
01295   
01296   msTimeStamp_t ts = cfed->TimeStamp();
01297   std::map<msTimeStamp_t,cfEventData*>::iterator mitr = edmap.find(ts);
01298   if ( mitr == edmap.end() ) {
01299     // event time not there, just add it
01300     if ( cfg.Verbose > 2 ) {
01301       std::cout << "#CF2RR# adopt new time for cfEventData " << cfed 
01302                 << " @ " << cfed->TimeStamp()
01303                 << "   " << cfed->EarliestTime()
01304                 << " ndev " << cfed->Devices().size()
01305                 << std::endl;
01306     }
01307     edmap.insert( std::pair<msTimeStamp_t,cfEventData*>(ts,cfed) );
01308   } else {
01309     // one already exists for this time
01310     if ( cfg.Verbose > 2 ) {
01311       std::cout << "#CF2RR# adopt means merge for cfEventData " << cfed 
01312                 << " @ " << cfed->TimeStamp()
01313                 << "   " << cfed->EarliestTime()
01314                 << " ndev " << cfed->Devices().size()
01315                 << " into " << mitr->second 
01316                 << " ndev " << mitr->second->Devices().size()
01317                 << std::endl;
01318     }
01319     if ( cfg.Verbose > 0 ) {
01320       std::cout << "AdoptEvent() merge for time " << ts << std::endl;
01321     }
01322     mitr->second->MergeEvent(cfed);
01323     if ( cfg.Verbose > 2 ) {
01324       std::cout << "#CF2RR# merged1 cfEventData ndev " 
01325                 << mitr->second->Devices().size() << std::endl;
01326     }
01327     delete cfed;
01328     if ( cfg.Verbose > 2 ) {
01329       std::cout << "#CF2RR# merged2 cfEventData ndev " 
01330                 << mitr->second->Devices().size() << std::endl;
01331     }
01332   }
01333 }

void cfProcessor::CheckPointReport ( std::string  state  ) 

Definition at line 1623 of file cf2rr.cc.

References gSystem().

Referenced by main().

01624 {
01625   std::cout << "cfProcessor::CheckPointReport(\"" << state << "\") ";
01626 
01627   struct ProcInfo_t procinfo;
01628   gSystem->GetProcInfo(&procinfo);
01629   std::cout << " procinfo: "
01630             << std::setw(7) << procinfo.fCpuUser
01631             << "+" 
01632             << std::setw(7) << procinfo.fCpuSys
01633             << "s, RES "
01634             << std::setw(6) << procinfo.fMemResident
01635             << "KB, VIRT "
01636             << std::setw(6) << procinfo.fMemVirtual
01637             << "KB"
01638             << std::endl;
01639 
01640 }

void cfProcessor::ExpandFileList (  ) 

Definition at line 1084 of file cf2rr.cc.

References cfg, cfCfg::FileList, cfCfg::FilePatterns, Munits::g, len, cfCfg::Paths, and cfCfg::PrintOpts.

Referenced by main().

01084                                  {
01085 
01086   // separate out path directories
01087 
01088   // expand to find files
01089   glob_t g;  // glob structure for list of files 
01090   g.gl_pathc = 0; // not initialized by default?
01091   int glob_flags = GLOB_TILDE;  // expand ~ home directory
01092 
01093   std::ostringstream patterntext;  // for info/error messages
01094   std::ostringstream dirstext;     // for info/error messages
01095 
01096   // loop over file patterns
01097   std::vector<std::string>::const_iterator patitr = cfg.FilePatterns.begin();
01098   int ipatt = 0;
01099   for ( ; patitr != cfg.FilePatterns.end(); ++patitr, ++ipatt ) {
01100     std::string pattern = *patitr;
01101     patterntext << "\n\t" << pattern;
01102 
01103     // loop over directory paths
01104     std::vector<std::string>::const_iterator pathitr = cfg.Paths.begin();
01105     for ( ; pathitr != cfg.Paths.end(); ++pathitr ) {
01106       std::string pathalt = *pathitr;
01107       // if non-null, does it end with a "/"?   if not, add one
01108       size_t len = pathalt.size();
01109       if ( len > 0 && pathalt.rfind('/') != len-1 ) pathalt.append("/");
01110       if ( patitr == cfg.FilePatterns.begin() ) dirstext << "\n\t" << pathalt;
01111 
01112       // combination of path + wildcard-pattern
01113       std::string fullpattern = pathalt + pattern;
01114 
01115       glob(fullpattern.c_str(),glob_flags,NULL,&g);
01116       // if we found some, next glob() will append to list
01117       if ( g.gl_pathc > 0 ) glob_flags |= GLOB_APPEND;
01118 
01119     }
01120   }
01121 
01122   // add files to map, squeeze out duplicates
01123   int nfiles = g.gl_pathc;
01124   //std::cerr << "RWH nfiles " << nfiles << std::endl << std::flush;
01125   for (int ifile=0; ifile < nfiles; ++ifile) {
01126     std::string afile(g.gl_pathv[ifile]);
01127     //std::cerr << "RWH insert(" << afile << ")" << std::endl << std::flush;
01128     cfg.FileList.insert(afile);
01129   }
01130 
01131   // print the list of files?
01132   bool pFiles = ( cfg.PrintOpts.find("file") != std::string::npos );
01133   if ( pFiles ) {
01134     int indx = 0;
01135     std::set<std::string>::const_iterator flitr = cfg.FileList.begin();
01136     for ( ; flitr != cfg.FileList.end(); ++flitr, ++indx ) {
01137       if ( 0 == indx ) std::cout << "  FileLists: " << std::endl;
01138       std::cout << "     [" << std::setw(4) << indx << "] " 
01139                 << *flitr << std::endl;
01140     }
01141     std::cout << std::endl;
01142   }
01143 }

std::string cfProcessor::GuessEventLabel ( const std::string &  fname  ) 

Definition at line 1642 of file cf2rr.cc.

References TokenizeString().

Referenced by ReadOneFile().

01642                                                              {
01643   // in cases where the first line _isn't_ the event line that it 
01644   // should be then guess at the event label because we've pre-classified
01645   // the collector files
01646 
01647   std::vector<std::string> pathelements = TokenizeString(fname,"/",false);
01648 
01649   // assume first path element with a "," is the event label
01650   for ( size_t i = 0; i < pathelements.size(); ++i ) {
01651     std::string& element = pathelements[i];
01652     if ( element.find(",") != std::string::npos ) return element;
01653   }
01654 
01655   return "z,unknown-trig";
01656 }

void cfProcessor::MergeAdjacent (  ) 

Definition at line 1335 of file cf2rr.cc.

References cfg, cfEventData::EarliestTime(), edmap, cfCfg::Epsilon, cfCfg::MinDevices, cfCfg::TimeStampStart, and cfCfg::TimeStampStop.

Referenced by main().

01335                                 {
01336 
01337   size_t nrec = edmap.size();
01338   std::cout << "cfProcessor::MergeAdjacent() " << nrec << std::endl;
01339   if ( nrec < 2 ) return;  // need at least two entries to do any merge
01340 
01341   // sorting happens naturally from map<>
01342 
01343   std::map<msTimeStamp_t,cfEventData*>::iterator mitr, pitr;
01344 
01345   // make a pass through merging events with an upstream element
01346   // if they are within cfg.Epsilon of each other
01347   // if one is merged then remove it from the value part of the map
01348   pitr = edmap.begin();
01349   mitr = edmap.begin(); ++mitr;
01350   for ( ; mitr != edmap.end(); ++mitr ) {
01351     if ( mitr == pitr ) continue;  // don't merge w/ self
01352     msTimeStamp_t dt = mitr->second->EarliestTime() -
01353                        pitr->second->EarliestTime();
01354     size_t ndev = mitr->second->Devices().size();
01355     if ( abs(dt) < cfg.Epsilon || ndev < cfg.MinDevices ) {
01356       // needs merging, don't mess w/ map element per se (i.e. don't
01357       // try to erase() based on iterator (makes a mess of the map
01358       // as it can cause restructuring) just zero out pointer value
01359       cfEventData* tobeMerged = mitr->second;
01360       mitr->second = 0;
01361       pitr->second->MergeEvent(tobeMerged);
01362     } else {
01363       pitr = mitr;
01364     }
01365   }
01366 
01367   // do a pass eliminating events outside the window and map entries
01368   // who's values have been merged into previous records (and thus value=0)
01369   // take special care to move iterator on as erase() will invalidate
01370   mitr = edmap.begin();
01371   while ( mitr != edmap.end() ) {
01372     cfEventData* cfed = mitr->second;
01373     bool remove = false;
01374     if ( ! cfed ) {
01375       // data was merged with another event, all that is left in the
01376       // map is the key
01377       remove = true;
01378     } else {
01379       msTimeStamp_t earliest_ms = cfed->EarliestTime();
01380       // reject events that after merging might be outside our window
01381       if ( earliest_ms < cfg.TimeStampStart ||
01382            earliest_ms > cfg.TimeStampStop     ) remove = true;
01383     }
01384     if ( remove ) {
01385       // remove it from map (post-increment iterator)
01386       edmap.erase(mitr++);
01387     } else {
01388       // just move on
01389       ++mitr;
01390     }
01391   }
01392 }

void cfProcessor::PrintStatistics (  ) 

Definition at line 1544 of file cf2rr.cc.

References cfg, cfEventData::Devices(), devlist, edmap, faketriglist, LocalTimeString(), cfEventData::NumMerged(), cfCfg::TimeStampStart, cfCfg::TimeStampStop, triglist, and UTCTimeString().

Referenced by main().

01544                                   {
01545   std::cout << "------------------------------------------------" << std::endl;
01546   std::cout << "cfProcessor::PrintStatistics() " << edmap.size() 
01547             << " unique times, " << devlist.size() << " unique devices"
01548             << std::endl;
01549 
01550   std::cout << "  TimeStampStart " << std::setw(14) << cfg.TimeStampStart
01551             << " (ms) " << UTCTimeString(cfg.TimeStampStart) << std::endl
01552             << std::setw(17+14+6) << " " << LocalTimeString(cfg.TimeStampStart)
01553             << std::endl
01554             << "  TimeStampStop  " << std::setw(14) << cfg.TimeStampStop
01555             << " (ms) " << UTCTimeString(cfg.TimeStampStop) << std::endl
01556             << std::setw(17+14+6) << " " << LocalTimeString(cfg.TimeStampStop)
01557             << std::endl;
01558 
01559   std::map<size_t,size_t> devcnt;  // 1=#device 2=#spills w/ that #devices
01560   std::map<size_t,size_t> mrgcnt;  // 1=#merged 2=#devices
01561   std::map<size_t,size_t> valcnt;  // 1=#values 2=#devices
01562 
01563   std::map<msTimeStamp_t,cfEventData*>::const_iterator mitr = edmap.begin();
01564   for ( ; mitr != edmap.end(); ++mitr ) {
01565     cfEventData* ed = mitr->second;
01566     const std::map<std::string,cfDeviceData*>& devmap = ed->Devices();
01567     size_t ndev = devmap.size();
01568     devcnt[ndev]++;  // count it
01569     size_t nmerge = ed->NumMerged();
01570     mrgcnt[nmerge]++;
01571 
01572     std::map<std::string,cfDeviceData*>::const_iterator devitr = devmap.begin();
01573     for ( ; devitr != devmap.end(); ++devitr ) {
01574       size_t nval = devitr->second->Values().size();
01575       valcnt[nval]++;
01576     }
01577   }
01578 
01579   //std::cout << "------------------------------------------------" << std::endl;
01580   std::cout << "--- devices/record ---" << std::endl;
01581   std::map<size_t,size_t>::iterator dcitr = devcnt.begin();
01582   for ( ; dcitr != devcnt.end(); ++dcitr ) {
01583     std::cout << " saw " << std::setw(4) << dcitr->first << " devices "
01584               <<  std::setw(5) << dcitr->second << " times" << std::endl;
01585   }
01586 
01587   //std::cout << "------------------------------------------------" << std::endl;
01588   std::cout << "--- separate collector sets/record ---" << std::endl;
01589   std::map<size_t,size_t>::iterator mcitr = mrgcnt.begin();
01590   for ( ; mcitr != mrgcnt.end(); ++mcitr ) {
01591     std::cout << " saw " << std::setw(4) << mcitr->first << " events merged "
01592               <<  std::setw(5) << mcitr->second << " times" << std::endl;
01593   }
01594 
01595   //std::cout << "------------------------------------------------" << std::endl;
01596   std::cout << "--- data values/device ---" << std::endl;
01597   std::map<size_t,size_t>::iterator vcitr = valcnt.begin();
01598   for ( ; vcitr != valcnt.end(); ++vcitr ) {
01599     std::cout << " saw " << std::setw(4) << vcitr->first 
01600               << " values for a device "
01601               <<  std::setw(7) << vcitr->second << " times" << std::endl;
01602   }
01603 
01604   std::cout << "------------------------------------------------" << std::endl;
01605 
01606   std::map<std::string,size_t>::const_iterator titr = triglist.begin();
01607   for ( ; titr != triglist.end(); ++titr ) {
01608     std::cout << " trigger " << std::setw(12) << titr->first
01609               << " seen " << std::setw(8)
01610               << titr->second << " times " << std::endl;
01611   }   
01612   titr = faketriglist.begin();
01613   for ( ; titr != faketriglist.end(); ++titr ) {
01614     std::cout << " trigger " << std::setw(12) << titr->first
01615               << " faked " << std::setw(8)
01616               << titr->second << " times " << std::endl;
01617   }   
01618 
01619   std::cout << "------------------------------------------------" << std::endl;
01620 
01621 }

void cfProcessor::ReadFiles (  ) 

Definition at line 1145 of file cf2rr.cc.

References cfg, cfCfg::FileList, and ReadOneFile().

Referenced by main().

01145                             {
01146   std::cout << "cfProcessor::ReadFiles()" << std::endl;
01147 
01148   int indx = 0;
01149   std::set<std::string>::const_iterator flitr = cfg.FileList.begin();
01150   for ( ; flitr != cfg.FileList.end(); ++flitr, ++indx ) {
01151     ReadOneFile(*flitr);
01152   }
01153 }

void cfProcessor::ReadOneFile ( const std::string &  fname  ) 

Definition at line 1155 of file cf2rr.cc.

References cfEventData::AdoptDeviceData(), AdoptEvent(), cf2rr_nosuchfile, cfg, cfEventData::Delay(), delays, cfDeviceData::DeviceFullName(), cfEventData::Devices(), devlist, cfEventData::EarliestTime(), cfEventData::Entry(), etints, cfEventData::EventTriggerInt(), exename, exit(), cfCfg::ExitDevUnpackErr, faketriglist, cfEventData::Filename(), GuessEventLabel(), infile, cfDeviceData::IsCorrupt(), cfCfg::MergeWindow, cfEventData::PreSubT(), cfCfg::PrintOpts, cfEventData::TimeStamp(), cfCfg::TimeStampStart, cfCfg::TimeStampStop, TokenizeString(), cfEventData::Trigger(), triglist, and cfCfg::Verbose.

Referenced by ReadFiles().

01155                                                     {
01156   std::cout << "cfProcessor::ReadOneFile(\"" << fname << "\")" << std::endl;
01157   
01158   ifzstream infile(fname.c_str());
01159   if ( infile.fail() ) {
01160     std::cerr << "failed to find file \"" << fname << "\"" << std::endl;
01161     exit(cf2rr_nosuchfile);
01162   }
01163 
01164   bool pTrig = ( (cfg.PrintOpts.find("trigger") != std::string::npos) ||
01165                  (cfg.PrintOpts.find("event")   != std::string::npos)   );
01166   bool pDev  = (  cfg.PrintOpts.find("device")  != std::string::npos    );
01167 
01168   bool pExitErr = cfg.ExitDevUnpackErr;
01169 
01170   msTimeStamp_t preMergeStart = cfg.TimeStampStart - cfg.MergeWindow;
01171   msTimeStamp_t preMergeStop  = cfg.TimeStampStop  + cfg.MergeWindow;
01172 
01173   int32_t entry = 0, delayadd = 0;
01174   bool skip = false;
01175   cfEventData* cfed = 0;
01176   std::string line;
01177 
01178   while ( std::getline(infile, line) ) {
01179     if ( '*' == line[0] ) {
01180       //-------------------------------------------------------------------
01181       // start of new event
01182       //-------------------------------------------------------------------
01183       skip = false;  // new event always clears skip
01184       // if we have one in progress, then add it to our list and create new one
01185       if ( cfed ) {
01186         if ( cfg.Verbose > 2 ) {
01187           std::cout << "#CF2RR# adopt cfEventData " << cfed
01188                     << " @ " << cfed->TimeStamp()
01189                     << "   " << cfed->EarliestTime()
01190                     << " ndev " << cfed->Devices().size()
01191                     << std::endl;
01192         }
01193         AdoptEvent(cfed);
01194         cfed = 0;
01195       }
01196       cfed = new cfEventData(fname,entry,line,pTrig);
01197       triglist[cfed->Trigger()]++;
01198       delayadd = ( (cfed->PreSubT(0)) ? cfed->Delay(0) : 0 );
01199       etints[cfed->EventTriggerInt(0)]++;
01200       delays[cfed->Delay(0)]++;
01201 
01202       if ( cfg.Verbose > 2 ) {
01203         std::cout << "#CF2RR# create new cfEventData " << cfed
01204                   << " @ " << cfed->TimeStamp()
01205                   << std::endl;
01206       }
01207       ++entry;
01208       // is this 'event' outside our time window +/- merging epsilon?
01209       // for now accept events with the Epsilon on both sides
01210       // so that merging happens correctly
01211       // only after merging can we make a final cut
01212       if ( cfed->TimeStamp() < preMergeStart ||
01213            cfed->TimeStamp() > preMergeStop     ) {
01214         if ( cfg.Verbose > 1 ) {
01215           std::cout << "skip " 
01216                     << cfed->Trigger() << " " << cfed->TimeStamp()
01217                     << " entry " << std::setw(3) << cfed->Entry()
01218                     << " in " << cfed->Filename()
01219                     << std::endl;
01220         }
01221         // yes?  enable skipping device data until we see new event
01222         if ( cfg.Verbose > 2 ) {
01223           std::cout << "#CF2RR# oooh bad time, skip cfEventData " << cfed
01224                     << " @ " << cfed->TimeStamp()
01225                     << std::endl;
01226         }
01227         skip = true;
01228         delete cfed;
01229         cfed = 0;
01230       }
01231     } else {
01232       //-------------------------------------------------------------------
01233       // must be device data
01234       //-------------------------------------------------------------------
01235       if ( ! skip && ! cfed ) {
01236         std::cerr << exename << ": file \"" << fname << "\" "
01237           " didn't start with 'event', try to create one" << std::endl;
01238         //WAS// exit(cf2rr_firstlinenotevt);
01239         // fake it, create fake event line
01240         std::string evtlabel = GuessEventLabel(fname);
01241         // [0]=device [1]=time [2]=units [3]=scalar [4]=vector-values
01242         std::string timestr = TokenizeString(line," \t",true)[1];
01243         static const std::string star  = std::string("*");
01244         static const std::string blank = std::string(" ");
01245         std::string eventline = star + evtlabel + blank + timestr;
01246         skip = false;  // new event always clears skip
01247         cfed = new cfEventData(fname,entry,eventline,pTrig);
01248         faketriglist[cfed->Trigger()]++;
01249         delayadd = ( (cfed->PreSubT(0)) ? cfed->Delay(0) : 0 );
01250         etints[cfed->EventTriggerInt(0)]++;
01251         delays[cfed->Delay(0)]++;
01252 
01253         std::cerr << "#CF2RR# create missing cfEventData " << cfed
01254                   << " @ " << cfed->TimeStamp() << " " << cfed->Trigger()
01255                   << std::endl;
01256         ++entry;
01257       }
01258       if ( ! skip ) {
01259         if ( cfg.Verbose > 3 ) {
01260           std::cout << "#CF2RR# add device data to cfEventData " << cfed
01261                     << " @ " << cfed->TimeStamp()
01262                     << "   " << cfed->EarliestTime()
01263                     << std::endl;
01264         }
01265         cfDeviceData* cfdd = new cfDeviceData(line,delayadd,pExitErr,pDev);
01266         if ( cfdd->IsCorrupt() ) {
01267           delete cfdd;
01268         } else {
01269           devlist[cfdd->DeviceFullName()]++; // count #each device we see
01270           cfed->AdoptDeviceData(cfdd);
01271         }
01272         cfdd = 0;
01273       }
01274     }
01275   }
01276 
01277   // finish off last event
01278   if ( cfed ) {
01279     if ( cfg.Verbose > 2 ) {
01280       std::cout << "#CF2RR# adopt final cfEventData " << cfed
01281                 << " @ " << cfed->TimeStamp()
01282                 << "   " << cfed->EarliestTime()
01283                 << " ndev " << cfed->Devices().size()
01284                 << std::endl;
01285     }
01286     AdoptEvent(cfed);
01287     cfed = 0;
01288   }
01289 
01290   //not for ifzstream// infile.close();
01291 
01292 }

int32_t cfProcessor::SendToRotorooter (  ) 

time of window start

Definition at line 1394 of file cf2rr.cc.

References BeamData::add_device_value(), cfCfg::AllowRotoErrors, bd, cfg, BeamData::close_connection(), BeamData::close_file(), cfEventData::Delay(), delays, cfDeviceData::DeviceFullName(), cfEventData::Devices(), cfEventData::EarliestTime(), edmap, etints, cfEventData::EventTriggerInt(), exename, BeamData::open_connection(), BeamData::open_file(), cfCfg::RotoNode, BeamData::send_data(), BeamData::set_device_header(), BeamData::start_block(), cfDeviceData::TimeStamp(), TimeStamp2SecMilli(), TimeStamp2SecNano(), cfCfg::TimeStampStart, cfCfg::TimeStampStop, cfCfg::Verbose, and cfCfg::WriteEmptyFiles.

Referenced by main().

01394                                       {
01395 
01396   if ( edmap.empty() ) {
01397     if ( ! cfg.WriteEmptyFiles ) {
01398       std::cout << "cfProcessor::SendToRotorooter()"
01399                 << " - no records to write" 
01400                 << std::endl;
01401       return 0;  // we're done here
01402     } else {
01403       std::cout << "cfProcessor::SendToRotorooter()"
01404                 << " - no records, but empty file requested" 
01405                 << std::endl;
01406       // continue on
01407     }
01408   } else {
01409     std::cout << "cfProcessor::SendToRotorooter()"
01410               << " - process normally"
01411               << std::endl;
01412   }
01413 
01414   // (nb. should be getting triger event delay from data )
01415   // old data had 'tclk_event' = 169 = 0xA9,  'tclk_delay' = 500
01416   int32_t tclk_event = -1;
01417   int32_t tclk_delay = -1;
01418   size_t mxcnt = 0;
01419   // find more promenent
01420   std::map<int32_t,size_t>::const_iterator etitr = etints.begin();
01421   for ( mxcnt=0 ; etitr != etints.end(); ++etitr ) {
01422     if ( etitr->second > mxcnt ) tclk_event = etitr->first;
01423   }
01424   std::map<int32_t,size_t>::const_iterator dlitr = delays.begin();
01425   for ( mxcnt=0 ; dlitr != delays.end(); ++dlitr ) {
01426     if ( dlitr->second > mxcnt ) tclk_delay = dlitr->first;
01427   }
01428   // squalk if there is actually more than one combination
01429   if ( etints.size() != 1 || delays.size() != 1 || cfg.Verbose > 0 ) {
01430     std::cerr << exename << " is some combination of "
01431               << std::endl << "  triggers: ";
01432     for ( etitr = etints.begin(); etitr != etints.end(); ++etitr ) {
01433       std::cerr << "$" << std::hex << etitr->first << std::dec
01434                 << " [" << etitr->second << "x] ";
01435     }
01436     std::cerr << std::endl << "  delays: ";
01437     for ( dlitr = delays.begin(); dlitr != delays.end(); ++dlitr ) {
01438       std::cerr << dlitr->first << " [" << dlitr->second << "x] ";
01439     }
01440     std::cerr << std::endl;
01441   }
01442 
01443   //
01444   // Now, we need to start talking with the rotorooter by opening
01445   // the connection, send the data and close the connection.
01446   //
01447   int32_t conn_status = bd.open_connection(cfg.RotoNode.c_str());
01448   if ( conn_status != 0 ) {
01449     std::cerr << exename << ": failed to make rotorooter connection ("
01450               << conn_status << ")" << std::endl << std::flush;
01451     if ( ! cfg.AllowRotoErrors ) return conn_status;
01452   }
01453 
01454   //
01455   // Open a file in the rotorooter
01456   //
01457   // Do not use time of first spill in the window to name file
01458   // but instead use the start of the requested time window
01459   //
01460   nanoTSPair_t tsFile = TimeStamp2SecNano(cfg.TimeStampStart);
01461   int32_t file_status = bd.open_file(tsFile.first,tsFile.second); 
01462 
01463   if ( file_status != 0 ) {
01464     std::cerr << exename << ": failed to open rotorooter file ("
01465               << file_status << ")" << std::endl << std::flush;
01466     if ( ! cfg.AllowRotoErrors ) return file_status;
01467   }
01468 
01469   //
01470   // Loop over cfEventData/timestamps (in time order)
01471   //
01472   size_t ispill = 0;
01473   std::map<msTimeStamp_t,cfEventData*>::const_iterator mitr = edmap.begin();
01474   for ( ; mitr != edmap.end(); ++mitr, ++ispill ) {
01475     cfEventData* cfed = mitr->second;
01476 
01477     msTimeStamp_t earliest_ms = cfed->EarliestTime();
01478 
01479     // reject events that after merging might be outside our window
01480     if ( earliest_ms < cfg.TimeStampStart ||
01481          earliest_ms > cfg.TimeStampStop     ) continue;
01482 
01483     //
01484     // An 'event' might have been merged from "close" events
01485     // Choose the earliest time to tag the record
01486     //
01487     nanoTSPair_t tsEvent = TimeStamp2SecNano(earliest_ms);
01488 
01489     // Hopefully any merging of events all had the same trigger + delay
01490     tclk_event = cfed->EventTriggerInt(0);
01491     tclk_delay = cfed->Delay(0);
01492 
01493     //
01494     // Start a record (Brett calls this a block)
01495     //
01496     bd.start_block(tsEvent.first,tsEvent.second,ispill,
01497                    tclk_event, tclk_delay);
01498 
01499     //
01500     // Loop over devices in the 'event'
01501     //
01502     const std::map<std::string,cfDeviceData*>& devmap = cfed->Devices();
01503     // size_t ndev = devmap.size();
01504     std::map<std::string,cfDeviceData*>::const_iterator devitr = devmap.begin();
01505     for ( ; devitr != devmap.end(); ++devitr ) {
01506       cfDeviceData* dd = devitr->second;
01507       milliTSPair_t tsDevice = TimeStamp2SecMilli(dd->TimeStamp());
01508       const char*   name = dd->DeviceFullName().c_str(); // RWH: full name or sans [] ?
01509       //
01510       // Start the sub-block entry for this device
01511       // this wants time in sec + ms
01512       bd.set_device_header(name,tsDevice.first,tsDevice.second);
01513       //
01514       // loop over device values
01515       //
01516       const std::vector<double>& values = devitr->second->Values();
01517       size_t nval = values.size();
01518       for (size_t ival=0; ival < nval; ++ival ) {
01519         bd.add_device_value(name,values[ival]);
01520       } // loop over values
01521     } // loop over devices
01522     bd.send_data();  // finish off record/block/'event'
01523 
01524   } // loop over 'events'
01525 
01526   //
01527   // Close the file; Close the connection
01528   //
01529   file_status = bd.close_file();
01530   if ( file_status != 0 ) {
01531     std::cerr << exename << ": failed to close rotorooter file ("
01532               << file_status << ")" << std::endl << std::flush;
01533     if ( ! cfg.AllowRotoErrors ) return file_status;
01534   }
01535   conn_status = bd.close_connection();
01536   if ( conn_status != 0 ) {
01537     std::cerr << exename << ": failed to close rotorooter file ("
01538               << conn_status << ")" << std::endl << std::flush;
01539     if ( ! cfg.AllowRotoErrors ) return conn_status;
01540   }
01541   return 0;  // !! success
01542 }


Member Data Documentation

Definition at line 349 of file cf2rr.cc.

Referenced by SendToRotorooter().

cfCfg cfProcessor::cfg [protected]
std::map<int32_t,size_t> cfProcessor::delays [protected]

Definition at line 357 of file cf2rr.cc.

Referenced by ReadOneFile(), and SendToRotorooter().

std::map<std::string,size_t> cfProcessor::devlist [protected]

Definition at line 352 of file cf2rr.cc.

Referenced by PrintStatistics(), and ReadOneFile().

Definition at line 351 of file cf2rr.cc.

Referenced by AdoptEvent(), MergeAdjacent(), PrintStatistics(), SendToRotorooter(), and ~cfProcessor().

std::map<int32_t,size_t> cfProcessor::etints [protected]

Definition at line 356 of file cf2rr.cc.

Referenced by ReadOneFile(), and SendToRotorooter().

std::map<std::string,size_t> cfProcessor::faketriglist [protected]

Definition at line 354 of file cf2rr.cc.

Referenced by PrintStatistics(), and ReadOneFile().

std::map<std::string,size_t> cfProcessor::triglist [protected]

Definition at line 353 of file cf2rr.cc.

Referenced by PrintStatistics(), and ReadOneFile().


The documentation for this class was generated from the following file:

Generated on 15 Jul 2018 for loon by  doxygen 1.6.1