/******************************************************************************/ /* */ /* EVENTLIST.HH */ /* */ /******************************************************************************/ // Shourov K. Chatterji // shourov@ligo.caltech.edu // $Id: eventlist.hh,v 1.1 2006/11/03 15:33:59 shourov Exp $ /* Protect against double inclusion */ /* -------------------------------- */ #ifndef EVENTLIST_HH #define EVENTLIST_HH /* Include header files */ /* -------------------- */ #include #include #include #include #include #include "event.hh" #include "eventcriteria.hh" #include "segmentlist.hh" /* Begin namespace event */ /* --------------------- */ namespace event { /* Declare externally defined classes */ /* ---------------------------------- */ class CoincidentEventList; /* Begin class EventList */ /* --------------------- */ class EventList { /* Public interface of class EventList */ /* ----------------------------------- */ public: /* Constructor and destructor declarations */ /* --------------------------------------- */ // default eventlist constructor EventList(); // default eventlist destructor ~EventList(); // event list copy constructor EventList(const EventList& eventList); // event list assignment operator EventList& operator=(const EventList& eventList); // event list constructor from coincident event list EventList(const CoincidentEventList& coincidentEventList); /* Mutator method declarations */ /* --------------------------- */ // empty contents of event list void clear(); // cut event list by requested criterion template void cut(CutCriterion cutCriterion); // sort event list by requested criterion template void sort(SortCriterion sortCriterion); // extract the most significant of overlapping events template void select(SortCriterion sortCriterion, CoincidenceCriterion coincidenceCriterion); // remove events outside of segment list template void mask(const segment::SegmentList& segmentList, CoincidenceCriterion coincidenceCriterion); // time shift event list by specified duration void timeShift(double timeShift); /* Accessor method declarations */ /* ---------------------------- */ // get number of events std::vector::size_type getNumberOfEvents() const; /* Input/output method declarations */ /* -------------------------------- */ // write event list to file void write(std::string file) const; // read event list from file void read(std::string file); /* Friend function declarations */ /* ---------------------------- */ // write event list to output stream friend std::ostream& operator<<(std::ostream& ostream, const EventList& eventList); // read event list from input stream friend std::istream& operator>>(std::istream& istream, EventList& eventList); // compare two event lists template friend void compare(EventList& eventList1, EventList& eventList2, EventList& detectedEventList1, EventList& undetectedEventList1, EventList& detectedEventList2, EventList& undetectedEventList2, CoincidenceCriterion coincidenceCriterion); // compare observed event list against injected event list template friend void detect(EventList& observedEventList, EventList& injectedEventList, EventList& trueEventList, EventList& falseEventList, EventList& detectedEventList, EventList& missedEventList, CoincidenceCriterion coincidenceCriterion); // compare observed event list against veto event list template friend void veto(EventList& observedEventList, EventList& vetoEventList, EventList& vetoedEventList, EventList& acceptedEventList, EventList& appliedEventList, EventList& unappliedEventList, CoincidenceCriterion coincidenceCriterion); // test observed event list for detected injections template friend void detect(EventList& observedEventList, EventList& injectedEventList, EventList& detectedEventList, CoincidenceCriterion coincidenceCriterion); // test observed event list for veto survivors template friend void veto(EventList& observedEventList, EventList& vetoEventList, EventList& acceptedEventList, CoincidenceCriterion coincidenceCriterion); // coincide two event lists template friend void coincide(EventList& inputEventList1, EventList& inputEventList2, CoincidentEventList& outputCoincidentEventList, CoincidenceCriterion coincidenceCriterion); // coincide a coincident event list with an event list template friend void coincide(CoincidentEventList& inputCoincidentEventList, EventList& inputEventList, CoincidentEventList& outputCoincidentEventList, std::vector coincidenceCriteria); // coincide multiple event lists template friend void coincide(std::vector inputEventLists, CoincidentEventList& outputCoincidentEventList, std::vector coincidenceCriteria); /* Friend class declarations */ /* ------------------------- */ // allow coincident event lists to access private interface friend class CoincidentEventList; /* Protected interface of class EventList */ /* -------------------------------------- */ protected: /* Private interface of class EventList */ /* ------------------------------------ */ private: /* Private function declarations */ /* ----------------------------- */ // define status flags for down selection enum Status {test, pass, fail}; // recursively test event for more significant coincident events template void recursiveSelect(std::vector::iterator currentEvent, std::vector::iterator currentStatus, SortCriterion sortCriterion, CoincidenceCriterion coincidenceCriterion, double maximumDuration); /* State variables */ /* --------------- */ // vector of events std::vector eventVector; /* End class EventList */ /* ------------------- */ }; /* Non-member function declarations */ /* -------------------------------- */ // write event list to output stream std::ostream& operator<<(std::ostream& ostream, const EventList& eventList); // read event list from input stream std::istream& operator>>(std::istream& istream, EventList& eventList); // compare two event lists template void compare(EventList& eventList1, EventList& eventList2, EventList& detectedList1, EventList& undetectedList1, EventList& detectedList2, EventList& undetectedList2, CoincidenceCriterion coincidenceCriterion); // compare observed event list against injected event list template void detect(EventList& observedEventList, EventList& injectedEventList, EventList& trueEventList, EventList& falseEventList, EventList& detectedEventList, EventList& missedEventList, CoincidenceCriterion coincidenceCriterion); // compare observed event list against veto event list template void veto(EventList& observedEventList, EventList& vetoEventList, EventList& vetoedEventList, EventList& acceptedEventList, EventList& appliedEventList, EventList& unappliedEventList, CoincidenceCriterion coincidenceCriterion); // test observed event list for detected injections template void detect(EventList& observedEventList, EventList& injectedEventList, EventList& detectedEventList, CoincidenceCriterion coincidenceCriterion); // test observed event list for veto survivors template void veto(EventList& observedEventList, EventList& vetoEventList, EventList& acceptedEventList, CoincidenceCriterion coincidenceCriterion); /* Constructor and destructor definitions */ /* -------------------------------------- */ // default event list constructor EventList::EventList() { } // default event list destructor EventList::~EventList() { } // event list copy constructor EventList::EventList(const EventList& eventList) : eventVector(eventList.eventVector) { } // event list assignment operator EventList& EventList::operator=(const EventList& eventList) { if (this != &eventList) { eventVector = eventList.eventVector; } return *this; } /* Mutator method definitions */ /* -------------------------- */ // empty contents of event list void EventList::clear() { eventVector.clear(); } // cut event list by requested criterion template void EventList::cut(CutCriterion cutCriterion) { std::vector::iterator removeIterator; removeIterator = std::remove_if(eventVector.begin(), eventVector.end(), cutCriterion); eventVector.erase(removeIterator, eventVector.end()); } // sort event list by requested criterion template void EventList::sort(SortCriterion sortCriterion) { std::sort(eventVector.begin(), eventVector.end(), sortCriterion); } // extract the most significant of overlapping events template void EventList::select(SortCriterion sortCriterion, CoincidenceCriterion coincidenceCriterion) { if (eventVector.size() == 0) { return; } sort(IncreasingEventCenterTimeSortCriterion()); std::vector::iterator maximumDurationEventIterator = std::max_element(eventVector.begin(), eventVector.end(), IncreasingEventDurationSortCriterion()); double maximumEventDuration = maximumDurationEventIterator-> getDuration(coincidenceCriterion.durationInflation); std::vector statusVector(eventVector.size(), test); std::vector::iterator eventIterator; std::vector::iterator statusIterator; eventIterator = eventVector.begin(); statusIterator = statusVector.begin(); while (eventIterator < eventVector.end()) { if (*statusIterator == test) { recursiveSelect(eventIterator, statusIterator, sortCriterion, coincidenceCriterion, maximumEventDuration); } eventIterator++; statusIterator++; } std::vector::iterator partitionIterator; eventIterator = eventVector.begin(); statusIterator = statusVector.begin(); partitionIterator = eventVector.begin(); while (eventIterator < eventVector.end()) { if (*statusIterator == pass) { *partitionIterator = *eventIterator; partitionIterator++; } eventIterator++; statusIterator++; } eventVector.erase(partitionIterator, eventVector.end()); } // recursively test event for more significant coincident events template void EventList::recursiveSelect(std::vector::iterator currentEventIterator, std::vector::iterator currentStatusIterator, SortCriterion sortCriterion, CoincidenceCriterion coincidenceCriterion, double maximumEventDuration) { std::vector::iterator eventIterator; std::vector::iterator statusIterator; double minimumCenterTime = currentEventIterator->getStartTime(coincidenceCriterion.durationInflation) - coincidenceCriterion.coincidenceWindowDuration - maximumEventDuration / 2.0; eventIterator = currentEventIterator - 1; statusIterator = currentStatusIterator - 1; while (eventIterator >= eventVector.begin()) { if (eventIterator->getCenterTime() < minimumCenterTime) { break; } if (!sortCriterion(*eventIterator, *currentEventIterator)) { if (coincidenceCriterion(*currentEventIterator, *eventIterator)) { if (*statusIterator == test) { recursiveSelect(eventIterator, statusIterator, sortCriterion, coincidenceCriterion, maximumEventDuration); } if (*statusIterator == pass) { *currentStatusIterator = fail; return; } } } eventIterator--; statusIterator--; } double maximumCenterTime = currentEventIterator->getStopTime(coincidenceCriterion.durationInflation) + coincidenceCriterion.coincidenceWindowDuration + maximumEventDuration / 2.0; eventIterator = currentEventIterator + 1; statusIterator = currentStatusIterator + 1; while (eventIterator < eventVector.end()) { if (eventIterator->getCenterTime() > maximumCenterTime) { break; } if (sortCriterion(*currentEventIterator, *eventIterator)) { if (coincidenceCriterion(*currentEventIterator, *eventIterator)) { if (*statusIterator == test) { recursiveSelect(eventIterator, statusIterator, sortCriterion, coincidenceCriterion, maximumEventDuration); } if (*statusIterator == pass) { *currentStatusIterator = fail; return; } } } eventIterator++; statusIterator++; } *currentStatusIterator = pass; } // remove events outside of segment list template void EventList::mask(const segment::SegmentList& segmentList, CoincidenceCriterion coincidenceCriterion) { if (eventVector.size() == 0) { return; } sort(IncreasingEventCenterTimeSortCriterion()); segment::SegmentList mergedSegmentList(segmentList); mergedSegmentList.merge(); std::vector::iterator maximumDurationEventIterator = std::max_element(eventVector.begin(), eventVector.end(), IncreasingEventDurationSortCriterion()); double maximumEventDuration = maximumDurationEventIterator-> getDuration(coincidenceCriterion.durationInflation); std::vector::iterator eventIterator; std::vector::iterator partitionIterator; std::vector::const_iterator segmentIterator; std::vector::const_iterator segmentStartIterator; std::vector::const_iterator segmentStopIterator; eventIterator = eventVector.begin(); partitionIterator = eventVector.begin(); segmentIterator = mergedSegmentList.segmentVector.begin(); segmentStartIterator = mergedSegmentList.segmentVector.begin(); segmentStopIterator = mergedSegmentList.segmentVector.begin(); while (eventIterator < eventVector.end()) { double startTime = eventIterator->getCenterTime() - maximumEventDuration / 2.0; double stopTime = eventIterator->getCenterTime() + maximumEventDuration / 2.0; while (segmentStartIterator < mergedSegmentList.segmentVector.end()) { if (segmentStartIterator->getStopTime() >= startTime) { break; } segmentStartIterator++; } while (segmentStopIterator < mergedSegmentList.segmentVector.end()) { if (segmentStopIterator->getStartTime() >= stopTime) { break; } segmentStopIterator++; } bool coincident = false; segmentIterator = segmentStartIterator; while (segmentIterator < segmentStopIterator) { if (coincidenceCriterion(*eventIterator, *segmentIterator)) { coincident = true; } segmentIterator++; } if (coincident == true) { *partitionIterator = *eventIterator; partitionIterator++; } eventIterator++; } eventVector.erase(partitionIterator, eventVector.end()); } // time shift event list by specified duration void EventList::timeShift(double timeShift) { std::vector::iterator eventIterator(eventVector.begin()); while (eventIterator < eventVector.end()) { eventIterator->timeShift(timeShift); eventIterator++; } } /* Accessor method definitions */ /* --------------------------- */ // get number of events std::vector::size_type EventList::getNumberOfEvents() const { return eventVector.size(); } /* Input/output method definitions */ /* ------------------------------- */ // write event list to file void EventList::write(std::string file) const { std::ofstream ofstream(file.c_str()); ofstream << *this; } // read event list from file void EventList::read(std::string file) { std::ifstream ifstream(file.c_str()); ifstream >> *this; if (ifstream.fail()) { std::cerr << "error: syntax error in event list " << file << std::endl; } } /* Non-member function definitions */ /* ------------------------------- */ // write event list to output stream std::ostream& operator<<(std::ostream& ostream, const EventList& eventList) { std::vector::const_iterator eventIterator; eventIterator = eventList.eventVector.begin(); while (eventIterator < eventList.eventVector.end()) { ostream << *eventIterator; eventIterator++; } return ostream; } // read event list from input stream std::istream& operator>>(std::istream& istream, EventList& eventList) { eventList.clear(); Event event; while (istream.peek() != EOF) { istream >> event; if (istream.fail()) { eventList.clear(); return istream; } eventList.eventVector.push_back(event); } return istream; } // compare two event lists template void compare(EventList& eventList1, EventList& eventList2, EventList& detectedEventList1, EventList& undetectedEventList1, EventList& detectedEventList2, EventList& undetectedEventList2, CoincidenceCriterion coincidenceCriterion) { if ((&detectedEventList1 == &eventList1) || (&detectedEventList1 == &eventList2) || (&undetectedEventList1 == &eventList1) || (&undetectedEventList1 == &eventList2) || (&detectedEventList2 == &eventList1) || (&detectedEventList2 == &eventList2) || (&undetectedEventList2 == &eventList1) || (&undetectedEventList2 == &eventList2)) { std::cerr << "error: event lists must be unique." << std::endl; return; } if ((eventList1.eventVector.size() == 0) || (eventList2.eventVector.size() == 0)) { detectedEventList1.eventVector.clear(); detectedEventList2.eventVector.clear(); undetectedEventList1.eventVector = eventList1.eventVector; undetectedEventList2.eventVector = eventList2.eventVector; return; } std::sort(eventList1.eventVector.begin(), eventList1.eventVector.end(), IncreasingEventCenterTimeSortCriterion()); std::sort(eventList2.eventVector.begin(), eventList2.eventVector.end(), IncreasingEventCenterTimeSortCriterion()); std::vector::iterator maximumDurationEventIterator1 = std::max_element(eventList1.eventVector.begin(), eventList1.eventVector.end(), IncreasingEventDurationSortCriterion()); std::vector::iterator maximumDurationEventIterator2 = std::max_element(eventList2.eventVector.begin(), eventList2.eventVector.end(), IncreasingEventDurationSortCriterion()); double maximumEventDuration1 = maximumDurationEventIterator1-> getDuration(coincidenceCriterion.durationInflation); double maximumEventDuration2 = maximumDurationEventIterator2-> getDuration(coincidenceCriterion.durationInflation); std::vector::iterator eventIterator1; std::vector::iterator eventIterator2; std::vector::iterator startIterator; std::vector::iterator stopIterator; eventIterator1 = eventList1.eventVector.begin(); eventIterator2 = eventList2.eventVector.begin(); startIterator = eventList2.eventVector.begin(); stopIterator = eventList2.eventVector.begin(); while (eventIterator1 < eventList1.eventVector.end()) { double startTime = eventIterator1->getCenterTime() - (maximumEventDuration1 + maximumEventDuration2) / 2.0 - coincidenceCriterion.coincidenceWindowDuration; double stopTime = eventIterator1->getCenterTime() + (maximumEventDuration1 + maximumEventDuration2) / 2.0 + coincidenceCriterion.coincidenceWindowDuration; startIterator = std::find_if(startIterator, eventList2.eventVector.end(), EventCenterTimeGreaterThanCutCriterion(startTime)); stopIterator = std::find_if(stopIterator, eventList2.eventVector.end(), EventCenterTimeGreaterThanCutCriterion(stopTime)); bool coincident = false; eventIterator2 = startIterator; while (eventIterator2 < stopIterator) { if (coincidenceCriterion(*eventIterator1, *eventIterator2)) { coincident = true; break; } eventIterator2++; } if (coincident) { detectedEventList1.eventVector.push_back(*eventIterator1); } else { undetectedEventList1.eventVector.push_back(*eventIterator1); } eventIterator1++; } eventIterator1 = eventList1.eventVector.begin(); eventIterator2 = eventList2.eventVector.begin(); startIterator = eventList1.eventVector.begin(); stopIterator = eventList1.eventVector.begin(); while (eventIterator2 < eventList2.eventVector.end()) { double startTime = eventIterator2->getCenterTime() - (maximumEventDuration1 + maximumEventDuration2) / 2.0 - coincidenceCriterion.coincidenceWindowDuration; double stopTime = eventIterator2->getCenterTime() + (maximumEventDuration1 + maximumEventDuration2) / 2.0 + coincidenceCriterion.coincidenceWindowDuration; startIterator = std::find_if(startIterator, eventList1.eventVector.end(), EventCenterTimeGreaterThanCutCriterion(startTime)); stopIterator = std::find_if(stopIterator, eventList1.eventVector.end(), EventCenterTimeGreaterThanCutCriterion(stopTime)); bool coincident = false; eventIterator1 = startIterator; while (eventIterator1 < stopIterator) { if (coincidenceCriterion(*eventIterator1, *eventIterator2)) { coincident = true; break; } eventIterator1++; } if (coincident) { detectedEventList2.eventVector.push_back(*eventIterator2); } else { undetectedEventList2.eventVector.push_back(*eventIterator2); } eventIterator2++; } } // compare observed event list against injected event list template void detect(EventList& observedEventList, EventList& injectedEventList, EventList& trueEventList, EventList& falseEventList, EventList& detectedEventList, EventList& missedEventList, CoincidenceCriterion coincidenceCriterion) { compare(observedEventList, injectedEventList, trueEventList, falseEventList, detectedEventList, missedEventList, coincidenceCriterion); } // compare observed event list against veto event list template void veto(EventList& observedEventList, EventList& vetoEventList, EventList& vetoedEventList, EventList& acceptedEventList, EventList& appliedEventList, EventList& unappliedEventList, CoincidenceCriterion coincidenceCriterion) { compare(observedEventList, vetoEventList, vetoedEventList, acceptedEventList, appliedEventList, unappliedEventList, coincidenceCriterion); } // test observed event list for detected injections template void detect(EventList& observedEventList, EventList& injectedEventList, EventList& detectedEventList, CoincidenceCriterion coincidenceCriterion) { if ((&detectedEventList == &observedEventList) || (&detectedEventList == &injectedEventList)) { std::cerr << "error: event lists must be unique." << std::endl; return; } if ((observedEventList.eventVector.size() == 0) || (injectedEventList.eventVector.size() == 0)) { detectedEventList.eventVector.clear(); return; } std::sort(observedEventList.eventVector.begin(), observedEventList.eventVector.end(), IncreasingEventCenterTimeSortCriterion()); std::sort(injectedEventList.eventVector.begin(), injectedEventList.eventVector.end(), IncreasingEventCenterTimeSortCriterion()); std::vector::iterator maximumDurationObservedEventIterator = std::max_element(observedEventList.eventVector.begin(), observedEventList.eventVector.end(), IncreasingEventDurationSortCriterion()); std::vector::iterator maximumDurationInjectedEventIterator = std::max_element(injectedEventList.eventVector.begin(), injectedEventList.eventVector.end(), IncreasingEventDurationSortCriterion()); double maximumObservedEventDuration = maximumDurationObservedEventIterator-> getDuration(coincidenceCriterion.durationInflation); double maximumInjectedEventDuration = maximumDurationInjectedEventIterator-> getDuration(coincidenceCriterion.durationInflation); std::vector::iterator observedEventIterator; std::vector::iterator injectedEventIterator; std::vector::iterator observedEventStartIterator; std::vector::iterator observedEventStopIterator; observedEventIterator = observedEventList.eventVector.begin(); injectedEventIterator = injectedEventList.eventVector.begin(); observedEventStartIterator = observedEventList.eventVector.begin(); observedEventStopIterator = observedEventList.eventVector.begin(); while (injectedEventIterator < injectedEventList.eventVector.end()) { double startTime = injectedEventIterator->getCenterTime() - (maximumObservedEventDuration + maximumInjectedEventDuration) / 2.0 - coincidenceCriterion.coincidenceWindowDuration; double stopTime = injectedEventIterator->getCenterTime() + (maximumObservedEventDuration + maximumInjectedEventDuration) / 2.0 + coincidenceCriterion.coincidenceWindowDuration; observedEventStartIterator = std::find_if(observedEventStartIterator, observedEventList.eventVector.end(), EventCenterTimeGreaterThanCutCriterion(startTime)); observedEventStopIterator = std::find_if(observedEventStopIterator, observedEventList.eventVector.end(), EventCenterTimeGreaterThanCutCriterion(stopTime)); bool detected = false; observedEventIterator = observedEventStartIterator; while (observedEventIterator < observedEventStopIterator) { if (coincidenceCriterion(*observedEventIterator, *injectedEventIterator)) { detected = true; break; } observedEventIterator++; } if (detected) { detectedEventList.eventVector.push_back(*injectedEventIterator); } injectedEventIterator++; } } // test observed event list for veto survivors template void veto(EventList& observedEventList, EventList& vetoEventList, EventList& acceptedEventList, CoincidenceCriterion coincidenceCriterion) { if ((&acceptedEventList == &observedEventList) || (&acceptedEventList == &vetoEventList)) { std::cerr << "error: event lists must be unique." << std::endl; return; } if ((observedEventList.eventVector.size() == 0) || (vetoEventList.eventVector.size() == 0)) { acceptedEventList.eventVector = observedEventList.eventVector; return; } std::sort(observedEventList.eventVector.begin(), observedEventList.eventVector.end(), IncreasingEventCenterTimeSortCriterion()); std::sort(vetoEventList.eventVector.begin(), vetoEventList.eventVector.end(), IncreasingEventCenterTimeSortCriterion()); std::vector::iterator maximumDurationObservedEventIterator = std::max_element(observedEventList.eventVector.begin(), observedEventList.eventVector.end(), IncreasingEventDurationSortCriterion()); std::vector::iterator maximumDurationVetoEventIterator = std::max_element(vetoEventList.eventVector.begin(), vetoEventList.eventVector.end(), IncreasingEventDurationSortCriterion()); double maximumObservedEventDuration = maximumDurationObservedEventIterator-> getDuration(coincidenceCriterion.durationInflation); double maximumVetoEventDuration = maximumDurationVetoEventIterator-> getDuration(coincidenceCriterion.durationInflation); std::vector::iterator observedEventIterator; std::vector::iterator vetoEventIterator; std::vector::iterator vetoEventStartIterator; std::vector::iterator vetoEventStopIterator; observedEventIterator = observedEventList.eventVector.begin(); vetoEventIterator = vetoEventList.eventVector.begin(); vetoEventStartIterator = vetoEventList.eventVector.begin(); vetoEventStopIterator = vetoEventList.eventVector.begin(); while (observedEventIterator < observedEventList.eventVector.end()) { double startTime = observedEventIterator->getCenterTime() - (maximumObservedEventDuration + maximumVetoEventDuration) / 2.0 - coincidenceCriterion.coincidenceWindowDuration; double stopTime = observedEventIterator->getCenterTime() + (maximumObservedEventDuration + maximumVetoEventDuration) / 2.0 + coincidenceCriterion.coincidenceWindowDuration; vetoEventStartIterator = std::find_if(vetoEventStartIterator, vetoEventList.eventVector.end(), EventCenterTimeGreaterThanCutCriterion(startTime)); vetoEventStopIterator = std::find_if(vetoEventStopIterator, vetoEventList.eventVector.end(), EventCenterTimeGreaterThanCutCriterion(stopTime)); bool vetoed = false; vetoEventIterator = vetoEventStartIterator; while (vetoEventIterator < vetoEventStopIterator) { if (coincidenceCriterion(*observedEventIterator, *vetoEventIterator)) { vetoed = true; break; } vetoEventIterator++; } if (!vetoed) { acceptedEventList.eventVector.push_back(*observedEventIterator); } observedEventIterator++; } } /* End namespace event */ /* ------------------- */ } /* End protection against double inclusion */ /* --------------------------------------- */ #endif