LCOV - code coverage report
Current view: top level - src/microsim/output - MSDetectorControl.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 94.6 % 93 88
Test Date: 2026-01-01 15:49:29 Functions: 100.0 % 13 13

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.
       4              : // This program and the accompanying materials are made available under the
       5              : // terms of the Eclipse Public License 2.0 which is available at
       6              : // https://www.eclipse.org/legal/epl-2.0/
       7              : // This Source Code may also be made available under the following Secondary
       8              : // Licenses when the conditions for such availability set forth in the Eclipse
       9              : // Public License 2.0 are satisfied: GNU General Public License, version 2
      10              : // or later which is available at
      11              : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
      12              : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
      13              : /****************************************************************************/
      14              : /// @file    MSDetectorControl.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Clemens Honomichl
      18              : /// @author  Sascha Krieg
      19              : /// @author  Michael Behrisch
      20              : /// @author  Laura Bieker
      21              : /// @date    2005-09-15
      22              : ///
      23              : // Detectors container; responsible for string and output generation
      24              : /****************************************************************************/
      25              : #include <config.h>
      26              : 
      27              : #include <iostream>
      28              : #include <utils/options/OptionsCont.h>
      29              : #include <utils/options/Option.h>
      30              : #include <utils/common/MsgHandler.h>
      31              : #include "MSMeanData_Emissions.h"
      32              : #include "MSMeanData_Net.h"
      33              : #include "MSDetectorControl.h"
      34              : 
      35              : 
      36              : // ===========================================================================
      37              : // member method definitions
      38              : // ===========================================================================
      39        40412 : MSDetectorControl::MSDetectorControl() {
      40        40412 : }
      41              : 
      42              : 
      43        39792 : MSDetectorControl::~MSDetectorControl() {
      44        51552 :     for (auto i = myDetectors.begin(); i != myDetectors.end(); ++i) {
      45        11760 :         (*i).second.clear();
      46              :     }
      47        62218 :     for (auto item : myMeanData) {
      48        45291 :         for (MSMeanData* md : item.second) {
      49        22865 :             delete md;
      50              :         }
      51              :     }
      52              :     myMeanData.clear();
      53        39792 : }
      54              : 
      55              : 
      56              : void
      57        38400 : MSDetectorControl::close(SUMOTime step) {
      58              :     // flush the last values
      59        38400 :     writeOutput(step, true);
      60              :     // [...] files are closed on another place [...]
      61              :     myIntervals.clear();
      62        38400 : }
      63              : 
      64              : 
      65              : void
      66        33186 : MSDetectorControl::add(SumoXMLTag type, MSDetectorFileOutput* d, const std::string& device, SUMOTime interval, SUMOTime begin) {
      67        33186 :     if (!myDetectors[type].add(d->getID(), d)) {
      68              :         const std::string id = d->getID();
      69            4 :         delete d;
      70           12 :         throw ProcessError(toString(type) + " detector '" + id + "' could not be built (declared twice?).");
      71              :     }
      72        33182 :     addDetectorAndInterval(d, &OutputDevice::getDevice(device), interval, begin);
      73        33168 : }
      74              : 
      75              : 
      76              : void
      77         3109 : MSDetectorControl::add(SumoXMLTag type, MSDetectorFileOutput* d) {
      78         3109 :     if (!myDetectors[type].add(d->getID(), d)) {
      79              :         const std::string id = d->getID();
      80            0 :         delete d;
      81            0 :         throw ProcessError(toString(type) + " detector '" + id + "' could not be built (declared twice?).");
      82              :     }
      83         3109 : }
      84              : 
      85              : 
      86              : void
      87        22942 : MSDetectorControl::add(MSMeanData* md, const std::string& device,
      88              :                        SUMOTime frequency, SUMOTime begin) {
      89        22942 :     myMeanData[md->getID()].push_back(md);
      90        22942 :     addDetectorAndInterval(md, &OutputDevice::getDevice(device), frequency, begin);
      91        45884 :     if (begin <= string2time(OptionsCont::getOptions().getString("begin"))) {
      92        22299 :         md->init();
      93              :     }
      94        22942 :     MSGlobals::gHaveEmissions |= typeid(*md) == typeid(MSMeanData_Emissions);
      95        22942 : }
      96              : 
      97              : 
      98              : const std::vector<SumoXMLTag>
      99         7773 : MSDetectorControl::getAvailableTypes() const {
     100              :     std::vector<SumoXMLTag> result;
     101         8265 :     for (std::map<SumoXMLTag, NamedObjectCont<MSDetectorFileOutput*> >::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
     102          492 :         result.push_back(i->first);
     103              :     }
     104         7773 :     return result;
     105            0 : }
     106              : 
     107              : 
     108              : const NamedObjectCont<MSDetectorFileOutput*>&
     109     11923634 : MSDetectorControl::getTypedDetectors(SumoXMLTag type) const {
     110     11923634 :     if (myDetectors.find(type) == myDetectors.end()) {
     111          102 :         return myEmptyContainer;
     112              :     }
     113     11923532 :     return myDetectors.find(type)->second;
     114              : }
     115              : 
     116              : 
     117              : void
     118     51793504 : MSDetectorControl::updateDetectors(const SUMOTime step) {
     119     63572366 :     for (const auto& i : myDetectors) {
     120     56594617 :         for (const auto& j : getTypedDetectors(i.first)) {
     121     44815755 :             j.second->detectorUpdate(step);
     122              :         }
     123              :     }
     124     78434908 :     for (auto item : myMeanData) {
     125     54189145 :         for (MSMeanData* md : item.second) {
     126     27547732 :             md->detectorUpdate(step);
     127              :         }
     128              :     }
     129     51793495 : }
     130              : 
     131              : 
     132              : void
     133     51831889 : MSDetectorControl::writeOutput(SUMOTime step, bool closing) {
     134     76870231 :     for (Intervals::iterator i = myIntervals.begin(); i != myIntervals.end(); ++i) {
     135     25038343 :         IntervalsKey interval = (*i).first;
     136     25038343 :         if (myLastCalls[interval] + interval.first <= step || (closing && myLastCalls[interval] < step)) {
     137       393907 :             DetectorFileVec dfVec = (*i).second;
     138       393907 :             SUMOTime startTime = myLastCalls[interval];
     139              :             // check whether at the end the output was already generated
     140      1491577 :             for (DetectorFileVec::iterator it = dfVec.begin(); it != dfVec.end(); ++it) {
     141      1097671 :                 MSDetectorFileOutput* det = it->first;
     142      1097671 :                 det->writeXMLOutput(*(it->second), startTime, step);
     143              :             }
     144       393906 :             myLastCalls[interval] = step;
     145       393907 :         }
     146              :     }
     147     51831888 : }
     148              : 
     149              : 
     150              : void
     151        56110 : MSDetectorControl::addDetectorAndInterval(MSDetectorFileOutput* det,
     152              :         OutputDevice* device,
     153              :         SUMOTime interval,
     154              :         SUMOTime begin) {
     155        56110 :     const SUMOTime simBegin = string2time(OptionsCont::getOptions().getString("begin"));
     156        56110 :     if (begin == -1) {
     157              :         begin = simBegin;
     158              :     }
     159        56110 :     IntervalsKey key = std::make_pair(interval, begin);
     160              :     Intervals::iterator it = myIntervals.find(key);
     161              :     // Add command for given key only once to MSEventControl...
     162        56110 :     if (it == myIntervals.end()) {
     163              :         DetectorFileVec detAndFileVec;
     164        23249 :         detAndFileVec.push_back(std::make_pair(det, device));
     165        46498 :         myIntervals.insert(std::make_pair(key, detAndFileVec));
     166              :         SUMOTime lastCall = begin;
     167        23249 :         if (begin < simBegin) {
     168           18 :             SUMOTime divRest = (simBegin - begin) % interval;
     169           18 :             lastCall = simBegin - divRest;
     170              :         }
     171        23249 :         myLastCalls[key] = lastCall;
     172        23249 :     } else {
     173        32861 :         DetectorFileVec& detAndFileVec = it->second;
     174        32861 :         if (find_if(detAndFileVec.begin(), detAndFileVec.end(), [&](const DetectorFilePair & pair) {
     175        96718 :         return pair.first == det;
     176              :     }) == detAndFileVec.end()) {
     177        32861 :             detAndFileVec.push_back(std::make_pair(det, device));
     178              :         } else {
     179              :             // detector already in container. Don't add several times
     180            0 :             WRITE_WARNING("MSDetectorControl::addDetectorAndInterval: detector already in container. Ignoring.");
     181            0 :             return;
     182              :         }
     183              :     }
     184        56110 :     det->writeXMLDetectorProlog(*device);
     185              : }
     186              : 
     187              : const std::map<std::string, MSMoveReminder*>&
     188          126 : MSDetectorControl::getAllReminders() {
     189          126 :     if (myReminders.empty()) {
     190           17 :         for (auto item : myMeanData) {
     191            2 :             for (MSMeanData* md : item.second) {
     192           45 :                 for (MSMoveReminder* rem : md->getReminders()) {
     193           44 :                     myReminders[rem->getDescription()] = rem;
     194            1 :                 }
     195              :             }
     196              :         }
     197           16 :         if (myReminders.empty()) {
     198              :             // ensure non-empty map
     199           15 :             myReminders[""] = nullptr;
     200              :         }
     201              :     }
     202          126 :     return myReminders;
     203              : }
     204              : 
     205              : void
     206          187 : MSDetectorControl::clearState(SUMOTime step) {
     207          247 :     for (const auto& i : myDetectors) {
     208          120 :         for (const auto& j : getTypedDetectors(i.first)) {
     209           60 :             j.second->clearState(step);
     210              :         }
     211              :     }
     212              :     myReminders.clear();
     213          187 : }
     214              : 
     215              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1