/******************************************************************************/ /* */ /* SEGMENTLIST.HH */ /* */ /******************************************************************************/ // Shourov K. Chatterji // shourov@ligo.caltech.edu // $Id: segmentlist.hh,v 1.1 2006/11/03 15:33:59 shourov Exp $ /* Protect against double inclusion */ /* -------------------------------- */ #ifndef SEGMENTLIST_HH #define SEGMENTLIST_HH /* Include header files */ /* -------------------- */ #include #include #include #include #include #include #include "segment.hh" #include "segmentcriteria.hh" /* Declare externally defined classes */ /* ---------------------------------- */ namespace event { class EventList; } /* Begin namespace segment */ /* ----------------------- */ namespace segment { /* Begin class SegmentList */ /* ----------------------- */ class SegmentList { /* Public interface of class SegmentList */ /* ------------------------------------- */ public: /* Constructor and destructor declarations */ /* --------------------------------------- */ // default segmentlist constructor SegmentList(); // default segmentlist destructor ~SegmentList(); // segment list copy constructor SegmentList(const SegmentList& segmentList); // segment list assignment operator SegmentList& operator=(const SegmentList& segmentList); /* Mutator method declarations */ /* --------------------------- */ // empty contents of segment list void clear(); // cut segment list by request criterion template void cut(CutCriterion cutCriterion); // sort segment list by request criterion template void sort(SortCriterion sortCriterion); // pad segments void pad(double padDuration); // trim segments void trim(double trimDuration); // merge overlapping segments void merge(); // split long segments void split(double maximumDuration, double overlap); // time shift segment list by specified duration void timeShift(double timeShift); // round times down to the nearest sample void align(double sampleFrequency = 1.0); /* Accessor method declarations */ /* ---------------------------- */ // get number of segments std::vector::size_type getNumberOfSegments() const; // get total livetime of segment list double getLiveTime() const; /* Input/output method declarations */ /* -------------------------------- */ // write segment list to file void write(std::string file) const; // read segment list from file void read(std::string file); /* Friend function declarations */ /* ---------------------------- */ // write segment list to output stream friend std::ostream& operator<<(std::ostream& ostream, const SegmentList& segmentList); // read segment list from input stream friend std::istream& operator>>(std::istream& istream, SegmentList& segmentList); // find inverse of a segment list friend SegmentList operator~(const SegmentList& segmentList); // find union of two segment lists friend SegmentList operator|(const SegmentList& segmentList1, const SegmentList& segmentList2); // find intersection of two segment lists friend SegmentList operator&(const SegmentList& segmentList1, const SegmentList& segmentList2); /* Friend class declarations */ /* ------------------------- */ // allow event lists to access private interface friend class event::EventList; /* Protected interface of class SegmentList */ /* ---------------------------------------- */ protected: /* Private interface of class SegmentList */ /* -------------------------------------- */ private: /* State variables */ /* --------------- */ // vector of segments std::vector segmentVector; /* End class SegmentList */ /* --------------------- */ }; /* Non-member function declarations */ /* -------------------------------- */ // write segment list to output stream std::ostream& operator<<(std::ostream& ostream, const SegmentList& segmentList); // read segment list from input stream std::istream& operator>>(std::istream& istream, SegmentList& segmentList); // find inverse of a segment list SegmentList operator~(const SegmentList& segmentList); // find union of two segment lists SegmentList operator|(const SegmentList& segmentList1, const SegmentList& segmentList2); // find intersection of two segment lists SegmentList operator&(const SegmentList& segmentList1, const SegmentList& segmentList2); /* Constructor and destructor definitions */ /* -------------------------------------- */ // default segment list constructor SegmentList::SegmentList() { } // default segment list destructor SegmentList::~SegmentList() { } // segment list copy constructor SegmentList::SegmentList(const SegmentList& segmentList) : segmentVector(segmentList.segmentVector) { } // segment list assignment operator SegmentList& SegmentList::operator=(const SegmentList& segmentList) { if (this != &segmentList) { segmentVector = segmentList.segmentVector; } return *this; } /* Mutator method definitions */ /* -------------------------- */ // empty contents of segment list void SegmentList::clear() { segmentVector.clear(); } // cut segment list by requested criterion template void SegmentList::cut(CutCriterion cutCriterion) { std::vector::iterator removeIterator; removeIterator = std::remove_if(segmentVector.begin(), segmentVector.end(), cutCriterion); segmentVector.erase(removeIterator, segmentVector.end()); } // sort segment list by requested criterion template void SegmentList::sort(SortCriterion sortCriterion) { std::sort(segmentVector.begin(), segmentVector.end(), sortCriterion); } // pad segments void SegmentList::pad(double padDuration) { std::vector::iterator segmentIterator; segmentIterator = segmentVector.begin(); while (segmentIterator < segmentVector.end()) { segmentIterator->setStartTime(segmentIterator->getStartTime() - padDuration); segmentIterator->setStopTime(segmentIterator->getStopTime() + padDuration); segmentIterator++; } } // trim segments void SegmentList::trim(double trimDuration) { pad(-trimDuration); } // merge overlapping segments void SegmentList::merge() { sort(IncreasingSegmentStartTimeSortCriterion()); std::vector::iterator mergedIterator; std::vector::iterator segmentIterator; mergedIterator = segmentVector.begin(); segmentIterator = segmentVector.begin(); segmentIterator++; SegmentCoincidenceCriterion coincidenceCriterion; while (segmentIterator < segmentVector.end()) { if (coincidenceCriterion(*segmentIterator, *mergedIterator)) { if (segmentIterator->getStopTime() > mergedIterator->getStopTime()) { mergedIterator->setStopTime(segmentIterator->getStopTime()); } } else { if (mergedIterator->getDuration() > 0.0) { mergedIterator++; } *mergedIterator = *segmentIterator; } segmentIterator++; } if (mergedIterator->getDuration() > 0.0) { mergedIterator++; } segmentVector.erase(mergedIterator, segmentVector.end()); } // split long segments void SegmentList::split(double maximumDuration, double overlap) { std::vector::iterator segmentIterator; segmentIterator = segmentVector.begin(); while (segmentIterator < segmentVector.end()) { if (segmentIterator->getDuration() > maximumDuration) { int numberOfSubSegments = static_cast(std::ceil((segmentIterator->getDuration() - overlap) / (maximumDuration - overlap))); double subSegmentDuration = overlap + (segmentIterator->getDuration() - overlap) / numberOfSubSegments; segmentIterator->setStopTime(segmentIterator->getStartTime() + subSegmentDuration); int subSegmentNumber = 1; while (subSegmentNumber < numberOfSubSegments) { double startTime = segmentIterator->getStartTime() + subSegmentNumber * (subSegmentDuration - overlap); double stopTime = startTime + subSegmentDuration; Segment segment(startTime, stopTime); segmentVector.push_back(segment); subSegmentNumber++; } } segmentIterator++; } sort(IncreasingSegmentStartTimeSortCriterion()); } // time shift segment list by specified duration void SegmentList::timeShift(double timeShift) { std::vector::iterator segmentIterator(segmentVector.begin()); while (segmentIterator < segmentVector.end()) { segmentIterator->timeShift(timeShift); segmentIterator++; } } // round times down to the nearest sample void SegmentList::align(double sampleFrequency) { std::vector::iterator segmentIterator(segmentVector.begin()); while (segmentIterator < segmentVector.end()) { segmentIterator->align(sampleFrequency); segmentIterator++; } } /* Accessor method definitions */ /* --------------------------- */ // get number of segments std::vector::size_type SegmentList::getNumberOfSegments() const { return segmentVector.size(); } // get total livetime of segment list double SegmentList::getLiveTime() const { double livetime = 0.0; std::vector::const_iterator segmentIterator; segmentIterator = segmentVector.begin(); while (segmentIterator < segmentVector.end()) { livetime += segmentIterator->getDuration(); segmentIterator++; } return livetime; } /* Input/output method definitions */ /* ------------------------------- */ // write segment list to file void SegmentList::write(std::string file) const { std::ofstream ofstream(file.c_str()); ofstream << *this; } // read segment list from file void SegmentList::read(std::string file) { std::ifstream ifstream(file.c_str()); ifstream >> *this; if (ifstream.fail()) { std::cerr << "error: syntax error in segment list " << file << std::endl; } } /* Non-member function definitions */ /* ------------------------------- */ // write segment list to output stream std::ostream& operator<<(std::ostream& ostream, const SegmentList& segmentList) { std::vector::const_iterator segmentIterator; segmentIterator = segmentList.segmentVector.begin(); while (segmentIterator < segmentList.segmentVector.end()) { ostream << *segmentIterator; segmentIterator++; } return ostream; } // read segment list from input stream std::istream& operator>>(std::istream& istream, SegmentList& segmentList) { segmentList.clear(); Segment segment; while (istream.peek() != EOF) { istream >> segment; if (istream.fail()) { segmentList.clear(); return istream; } segmentList.segmentVector.push_back(segment); } return istream; } // find inverse of a segment list SegmentList operator~(const SegmentList& segmentList) { SegmentList inverseSegmentList; if (segmentList.segmentVector.empty()) { Segment segment(-std::numeric_limits::infinity(), +std::numeric_limits::infinity()); inverseSegmentList.segmentVector.push_back(segment); return inverseSegmentList; } SegmentList mergedSegmentList(segmentList); mergedSegmentList.merge(); double stopTime; std::vector::iterator segmentIterator; segmentIterator = mergedSegmentList.segmentVector.begin(); if (segmentIterator->getStartTime() != -std::numeric_limits::infinity()) { Segment segment(-std::numeric_limits::infinity(), segmentIterator->getStartTime()); inverseSegmentList.segmentVector.push_back(segment); } stopTime = segmentIterator->getStopTime(); segmentIterator++; while (segmentIterator < mergedSegmentList.segmentVector.end()) { Segment segment(stopTime, segmentIterator->getStartTime()); inverseSegmentList.segmentVector.push_back(segment); stopTime = segmentIterator->getStopTime(); segmentIterator++; } if (stopTime != +std::numeric_limits::infinity()) { Segment segment(stopTime, +std::numeric_limits::infinity()); inverseSegmentList.segmentVector.push_back(segment); } return inverseSegmentList; } // find union of two segment lists SegmentList operator|(const SegmentList& segmentList1, const SegmentList& segmentList2) { SegmentList segmentList; std::vector::const_iterator segmentIterator; segmentIterator = segmentList1.segmentVector.begin(); while (segmentIterator < segmentList1.segmentVector.end()) { segmentList.segmentVector.push_back(*segmentIterator); segmentIterator++; } segmentIterator = segmentList2.segmentVector.begin(); while (segmentIterator < segmentList2.segmentVector.end()) { segmentList.segmentVector.push_back(*segmentIterator); segmentIterator++; } segmentList.merge(); return segmentList; } // find intersection of two segment lists SegmentList operator&(const SegmentList& segmentList1, const SegmentList& segmentList2) { SegmentList segmentList; if (segmentList1.segmentVector.empty() || segmentList2.segmentVector.empty()) { return segmentList; } SegmentList mergedSegmentList1(segmentList1); SegmentList mergedSegmentList2(segmentList2); mergedSegmentList1.merge(); mergedSegmentList2.merge(); std::vector::iterator segmentIterator1; std::vector::iterator segmentIterator2; segmentIterator1 = mergedSegmentList1.segmentVector.begin(); segmentIterator2 = mergedSegmentList2.segmentVector.begin(); while ((segmentIterator1 < mergedSegmentList1.segmentVector.end()) && (segmentIterator2 < mergedSegmentList2.segmentVector.end())) { if (segmentIterator2->getStartTime() >= segmentIterator1->getStopTime()) { segmentIterator1++; continue; } if (segmentIterator1->getStartTime() >= segmentIterator2->getStopTime()) { segmentIterator2++; continue; } double startTime; double stopTime; if (segmentIterator1->getStartTime() > segmentIterator2->getStartTime()) { startTime = segmentIterator1->getStartTime(); } else { startTime = segmentIterator2->getStartTime(); } if (segmentIterator1->getStopTime() < segmentIterator2->getStopTime()) { stopTime = segmentIterator1->getStopTime(); } else { stopTime = segmentIterator2->getStopTime(); } Segment segment(startTime, stopTime); segmentList.segmentVector.push_back(segment); if (segmentIterator1->getStopTime() < segmentIterator2->getStopTime()) { segmentIterator1++; } else { segmentIterator2++; } } return segmentList; } /* End namespace segment */ /* --------------------- */ } /* End protection against double inclusion */ /* --------------------------------------- */ #endif