private static void runIt(
      Network net, List<Link> linksLR, List<Link> linksRL, Scenario sc, double th, Setting s) {
    // visualization stuff
    EventsManager em = new EventsManagerImpl();
    // // // if (iter == 9)

    if (AbstractCANetwork.EMIT_VIS_EVENTS) {
      EventBasedVisDebuggerEngine vis = new EventBasedVisDebuggerEngine(sc);
      em.addHandler(vis);
      QSimDensityDrawer qDbg = new QSimDensityDrawer(sc);
      em.addHandler(qDbg);
      vis.addAdditionalDrawer(new InfoBox(vis, sc));
      vis.addAdditionalDrawer(qDbg);
    }
    CANetworkFactory fac;
    if (USE_MULTI_LANE_MODEL) {
      fac = new CAMultiLaneNetworkFactory();
      fac.setDensityEstimatorFactory(new CAMultiLaneDensityEstimatorSPHFactory());

    } else {
      fac = new CASingleLaneNetworkFactory();
      if (USE_SPH) {
        fac.setDensityEstimatorFactory(new CASingleLaneDensityEstimatorSPHFactory());
      } else {
        fac.setDensityEstimatorFactory(new CASingleLaneDensityEstimatorSPAFactory());
      }
    }

    CANetwork caNet = fac.createCANetwork(net, em, null);

    int agents = 0;
    {
      CAMultiLaneLink caLink = (CAMultiLaneLink) caNet.getCALink(linksLR.get(0).getId());
      int lanes = caLink.getNrLanes();
      CAMoveableEntity[] particles = caLink.getParticles(0);
      System.out.println("part left:" + particles.length);
      double oldR = 1;
      int tenth = particles.length / 10;
      int cnt = 0;
      for (int i = particles.length - 1; i >= 0; i--) {
        for (int lane = 0; lane < lanes; lane++) {
          double r = MatsimRandom.getRandom().nextDouble();
          if (r > th) {
            continue;
          }
          cnt++;
          if (cnt > s.pL) {
            break;
          }
          // agents++;
          CAMoveableEntity a =
              new CASimpleDynamicAgent(
                  linksLR, 1, Id.create("g" + agents++, CASimpleDynamicAgent.class), caLink);
          a.materialize(i, 1, lane);
          caLink.getParticles(lane)[i] = a;
          CASimAgentConstructEvent ee = new CASimAgentConstructEvent(0, a);
          em.processEvent(ee);

          CAEvent e =
              new CAEvent(
                  1 / (AbstractCANetwork.V_HAT * AbstractCANetwork.RHO_HAT),
                  a,
                  caLink,
                  CAEventType.TTA);
          caNet.pushEvent(e);
          caNet.registerAgent(a);
        }
      }
    }

    {
      CAMultiLaneLink caLink = (CAMultiLaneLink) caNet.getCALink(linksRL.get(0).getId());
      int lanes = caLink.getNrLanes();
      CAMoveableEntity[] particles = caLink.getParticles(0);
      System.out.println("part left:" + particles.length);
      double oldR = 1;
      int tenth = particles.length / 10;
      int cnt = 0;
      for (int i = 0; i < particles.length - 1; i++) {
        // for (int i = 0; i < 0; i++) {
        for (int lane = 0; lane < lanes; lane++) {
          double r = MatsimRandom.getRandom().nextDouble();
          if (r > th) {
            continue;
          }
          cnt++;
          if (cnt > s.pR) {
            break;
          }
          // agents++;
          CAMoveableEntity a =
              new CASimpleDynamicAgent(
                  linksRL, 1, Id.create("b" + agents++, CASimpleDynamicAgent.class), caLink);
          a.materialize(i, -1, lane);
          caLink.getParticles(lane)[i] = a;
          CASimAgentConstructEvent ee = new CASimAgentConstructEvent(0, a);
          em.processEvent(ee);

          CAEvent e =
              new CAEvent(
                  1 / (AbstractCANetwork.V_HAT * AbstractCANetwork.RHO_HAT),
                  a,
                  caLink,
                  CAEventType.TTA);
          caNet.pushEvent(e);
          caNet.registerAgent(a);
        }
      }
    }

    Monitor monitor =
        new CALinkMultiLaneMonitor((CAMultiLaneLink) caNet.getCALink(Id.createLinkId("2")), 3.);

    // CALinkMonitorExact monitor = new CALinkMonitorExactIIUni(
    // caNet.getCALink(Id.createLinkId("0")), 10.,
    // ((CAMultiLaneLink) caNet.getCALink(Id.createLinkId("0")))
    // .getParticles(0), caNet.getCALink(Id.createLinkId("0"))
    // .getLink().getCapacity());
    caNet.addMonitor(monitor);
    monitor.init();
    caNet.run(3600);
    try {
      monitor.report(bw);
      bw.flush();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
  @Override
  public void trigger(double time) {
    Measure m = new Measure();
    m.time = time;
    int cnt = 0;
    double dsCnt = 0;
    double usCnt = 0;
    double dsRho = 0;
    double usRho = 0;
    for (int lane = 0; lane < this.lanes; lane++) {
      CAMoveableEntity[] p = this.l.getParticles(lane);
      for (int i = this.from; i <= this.to; i++) {
        if (p[i] != null) {
          cnt++;
          m.in.add(p[i].getId());
          AgentInfo ai = this.ais.get(p[i].getId());
          // updateTimeRho(i, ai.dir, ai, time, p);
          if (p[i].getDir() == 1) {

            dsCnt++;
            // dsRho += ai.timeRho.get(time);
          } else {
            usCnt++;
            // usRho += ai.timeRho.get(time);
          }
        }
      }
    }
    double rho = cnt / this.a;

    m.rho = rho;
    m.dsRho = dsCnt / this.a;
    m.usRho = usCnt / this.a;
    // m.dsRho = dsRho / dsCnt;
    // m.usRho = usRho / usCnt;

    for (int lane = 0; lane < this.lanes; lane++) {
      CAMoveableEntity[] p = this.l.getParticles(lane);
      for (int i = 0; i < this.l.getNumOfCells(); i++) {
        CAMoveableEntity part = p[i];
        if (part != null) {
          Id id = part.getId();
          AgentInfo ai = this.ais.get(id);
          if (ai == null && (i == 0 || i == this.l.getNumOfCells() - 1)) {
            ai = new AgentInfo(part.getDir());
            // ai.lastPos = i;
            this.ais.put(id, ai);
          }
          if (ai.lastPos != i) {
            ai.timePos.put(time, i);
            ai.lastPos = i;
            if (i == 0) {
              if (part.getDir() == 1) {
                this.dsIn++;
              } else {
                this.usOut++;
              }
            } else if (i == this.l.getNumOfCells() - 1) {
              if (part.getDir() == 1) {
                this.dsOut++;
              } else {
                this.usIn++;
              }
            }
          }
        }
      }
    }
    if (m.rho > 0) {
      this.ms.add(m);
    }
  }