#include "IEventLoopStride.hxx" #include "IVInputFile.hxx" #include "ICOMETEvent.hxx" #include #include #include #include // random_shuffle, rotate, find #include "ICOMETLog.hxx" using namespace COMET; class Fixed:public IEventLoopStride{ public: Fixed(int stride):fStride(stride){} virtual int NextSkip(const ICOMETEvent& event){ int stride=fStride; // the event id is perhaps not the best way to get this, but this seems to work int event_id=event.GetEventId(); if(event_id+stride > fEntries) stride-=fEntries; return stride-1; } virtual bool NewEventSource(const char* filename, int entriesInFile, int firstEvent){ fEntries=entriesInFile; if(! WillCoverAllEvents(entriesInFile,fStride)){ std::cout << "ERROR: File '" << filename <<"' has a number of " "events ("< entriesInFile) stride = stride%entriesInFile; if(stride==1) return true; // now check if stride has a common factor with the number of // events return stride!=0 && entriesInFile%stride!=0 && stride%(entriesInFile%stride)!=0; } int fStride; int fEntries; }; class Prime:public Fixed{ public: Prime():Fixed(0){} virtual bool NewEventSource(const char* filename, int entriesInFile, int firstEvent){ fEntries=entriesInFile; const int ps_size=4; int possibleStrides[ps_size]={17,19,23,29}; int product=1; for(int i=0; i < ps_size; ++i){ fStride = possibleStrides[i]; product*=possibleStrides[i]; if (WillCoverAllEvents(entriesInFile,fStride)) break; fStride = 0; } if(fStride==0){ std::cout << "ERROR: File '" << filename <<"' cannot be used " "with the 'primes' stride mode since the number of events " "is a multiple of "<::iterator new_beginning = std::find(fEventOrder.begin(), fEventOrder.end(),firstEvent); // Move first event to front std::rotate(fEventOrder.begin(), new_beginning,fEventOrder.end()); // Move first event to front fEventIterator=fEventOrder.begin(); return true; } virtual int NextSkip(const ICOMETEvent& currentEvent){ int target=0; ++fEventIterator; if (fEventIterator==fEventOrder.end()){ target = fEntries; }else{ target = *(fEventIterator); } int event_id=currentEvent.GetEventId(); return target - event_id -1; } private: std::vector::const_iterator fEventIterator; std::vector fEventOrder; int fEntries; }; IEventLoopStride* COMET::BuildEventLoopStride(std::string request){ IEventLoopStride* strider=NULL; if(request=="random"){ strider=new Random(); } else if (request=="primes"){ strider=new Prime(); } else { std::istringstream tmp(request); int fixed_stride=0; if(tmp >> fixed_stride){ strider=new Fixed(fixed_stride); } } return strider; }