예제 #1
0
파일: suffrage.cpp 프로젝트: seato/suffrage
/*
 * Summary:     Given an array and a specific range [0, size) where the "size"_th
 *              iteration is not inclusive, return the iteration of the first
 *              instance of the specified key, or -1 if it does not exist.
 * Parameters:  u32 array to search, u32 size of the array, and the u32 element
 *              to locate.
 * Return:      Iteration of the first location of the key, -1 if it doesn't
 *              exist.
 */
u32
linearSearch(u32 a[], u32 size, u32 key)
{
  if (NULL == a) // null array pointer?
    {
      logNormal("linearSearch:  NULL array pointer!\n");
      API_ASSERT_NONNULL(a); // blinkcode!
    }

  if (size <= 0) // invalid size?
    {
      logNormal("linearSearch:  Invalid size %d\n", size);
      API_ASSERT_GREATER(size, 0); // blinkcode!
    }

  if (key < 0) // invalid key?
    {
      logNormal("linearSearch:  Invalid size %d\n", size);
      API_ASSERT_GREATER_EQUAL(size, 0); // blinkcode!
    }

  for (u32 i = 0; i < size; ++i)
    if (a[i] == key) // If there is a match
      return i; // say so

  return INVALID; // Otherwise, return the signal that there is no match
}
예제 #2
0
파일: suffrage.cpp 프로젝트: seato/suffrage
/*
 * Summary:     Handles (r)esult packet reflex.  Packet information is logged and
 *              result is logged for the specific calculation.
 * Parameters:  (r)esult packet.
 * Return:      None.
 */
void
r_handler(u8 * packet)
{
  R_PKT PKT_R;

  if (packetScanf(packet, "%Zr%z\n", R_ZScanner, &PKT_R) != 3)
    {
      logNormal("r_handler:  Failed at %d\n", packetCursor(packet));
      return; // No harm done so no blinkcoding necessary
    }

  u32 NODE_INDEX; // index holder for if log is valid

  // only log properly formatted packets
  if (INVALID == (NODE_INDEX = log(PKT_R.key.ID, PKT_R.key.TIME)))
    return; // Don't continue if this packet has been received before

  // Handle packet spammers
  else if (PC_NODE_ARR[NODE_INDEX] > (PKT_R.key.TIME / 1000))
    {
      // Decrease the amount of pings recorded; "spammer amnesty" of sorts.
      PC_NODE_ARR[NODE_INDEX] -= 2;
      return; // Don't continue if this IXM is spamming packets right now.
    }

  else if (PKT_R.calc_ver < HOST_CALC_VER)
    return; // Don't continue if this is an old calculation version

  else if (0xffffffff == PKT_R.calc_ver)
    logNormal("Calculation version overflow.\n");

  if (PKT_R.neighbor)
    { // If this a neighboring node
      PKT_R.neighbor = 0; // Reset the flag before forwarding
      NEIGHBORS_ARR[packetSource(packet)] = PKT_R.key.ID; // And remember the ID
    }

  // If all the hoops have been jumped through
  FWD_R_PKT(&PKT_R, packetSource(packet)); // Forward the packet

  if (PKT_R.calc_ver == HOST_CALC_VER) // Same result?
    // Update the results from packets with proper calculation versions
    voteCount(NODE_INDEX, PKT_R.rslt);

  else if (PKT_R.calc_ver > HOST_CALC_VER) // New calculation version?
    { // perform standard procedures
      strikeCheck(); // evaluate the strikes for my neighbors
      flush(); // clear out my records for the new voting session
      voteCount(NODE_INDEX, PKT_R.rslt); // Remember the node's vote
      HOST_CALC = PKT_R.calc; // Remember the new calculation
      HOST_CALC_VER = PKT_R.calc_ver; // Remember the new calculation version
      voteCount(0, calculate(HOST_CALC)); // calculation occurs here
    }

  return;
}
예제 #3
0
파일: suffrage.cpp 프로젝트: seato/suffrage
/*
 * Summary:     Adjusts the vote count based on a recent vote.
 * Parameters:  u32 index of the node that voted, u32 ballot of the node.
 * Return:      None.
 */
void
voteCount(u32 NODE_INDEX, u32 BALLOT)
{
  if (NODE_INDEX < 0)
    {
      logNormal("voteCount:  Invalid node index %d", NODE_INDEX);
      API_ASSERT_GREATER_EQUAL(NODE_INDEX, 0); // blinkcode!
    }

  if (BALLOT < 0)
    {
      logNormal("voteCount:  Invalid ballot %d", BALLOT);
      API_ASSERT_GREATER_EQUAL(BALLOT, 0); // blinkcode!
    }

  if (0 == BALLOT) // 0 is never a correct answer
    return; // But it's not worth blinkcoding over

  else if (BALLOT == VOTE_NODE_ARR[NODE_INDEX])
    return; // Ignore duplicate votes

  // Invalid vote if I've already voted (didn't flush from a new calculation)
  else if (0 != VOTE_NODE_ARR[NODE_INDEX])
    return;

  else if (0 == VOTE_NODE_ARR[NODE_INDEX]) // Haven't voted yet
    ++VOTE_COUNT; // This is the first vote received

  if (VOTE_COUNT > NODE_COUNT) // Someone voted multiple times
    {
      flush(); // Clean out memory
      voteCount(0, calculate(HOST_CALC)); // Recount our own vote
      return;
    }

  // look to see if the ballot is for an existing candidate
  u32 k = linearSearch(CANDIDATE_ARR, CANDIDATE_COUNT + 1, BALLOT);

  if (INVALID != k) // if so, give him a vote
    ++CANDIDATE_VOTES_ARR[k];

  else // otherwise the ballot is new to the candidate list
    { // so add it
      k = CANDIDATE_COUNT++; // Give him a vote
      CANDIDATE_ARR[k] = BALLOT; // Add the new candidate to the nominations list
      ++CANDIDATE_VOTES_ARR[k]; // Give the candidate a vote
    }

  VOTE_NODE_ARR[NODE_INDEX] = BALLOT; // record the node's ballot

  evalMajority(); //Reevaluate the majority with every different ballot

  return;
}
예제 #4
0
파일: suffrage.cpp 프로젝트: seato/suffrage
/*
 * Summary:     Logs the ID and time-stamp keys of a received packet.
 * Parameters:  u32 ID, u32 time-stamp (from a (r)esult packet)
 * Return:      Return index of the node if successful, otherwise INVALID.
 */
u32
log(u32 ID, u32 TIME)
{
  if (TIME < 0)
    {
      logNormal("log:  No time-traveling or overflow allowed!\n");
      API_ASSERT_GREATER_EQUAL(TIME, 0); // blinkcode!
    }

  for (u32 i = 0; i < NODE_COUNT; ++i)
    { // Look for an existing match in the list of previous PING'ers
      if (ID == ID_NODE_ARR[i])
        {
          if (TIME != TS_NODE_ARR[i])
            { // If there is a match and it is a new packet
              if (PC_NODE_ARR[i] < 0xffff) // Make sure ping count won't overflow
                ++PC_NODE_ARR[i]; // So we can keep track of the valid packet
              else
                // Notify us if the ping count will overflow
                logNormal("Limit of pings reached for IXM %t\n", ID);

              TS_NODE_ARR[i] = TIME; // Update nodular time-stamp
              TS_HOST_ARR[i] = millis(); // Update host-based time-stamp

              return i; // Return the location of the existing node
            }

          else
            // Don't forward the packet if it isn't new
            return INVALID;
        }
    }

  // Otherwise check to see if there is any free space left in the array
  if (NODE_COUNT >= (sizeof(ID_NODE_ARR) / sizeof(u32)))
    {
      logNormal("Inadequate memory space in ID table.\n"
        "Rebooting.\n");
      reenterBootloader(); // Clear out memory for new boards
    }

  // Add the new IXM board to the phone-book.
  ID_NODE_ARR[NODE_COUNT] = ID;
  TS_NODE_ARR[NODE_COUNT] = TIME;
  TS_HOST_ARR[NODE_COUNT] = millis();
  ++PC_NODE_ARR[NODE_COUNT];

  return NODE_COUNT++; // And pass it on
}
예제 #5
0
파일: suffrage.cpp 프로젝트: seato/suffrage
/*
 * Summary:     Custom (r)esult packet scanner.
 * Parameters:  The arguments are automatically handled within a parent
 *              header file.
 * Return:      Boolean confirming the packet was read correctly.
 */
bool
R_ZScanner(u8 * packet, void * arg, bool alt, int width)
{
  /* (r)esult packet structure */
  u32 ID; // hex ID (board key)
  u32 TIME; // integer timestamp (packet key)
  u32 CALC; // integer calculation
  u32 CALC_VER; // integer calculation version
  u32 VOTE; // integer vote
  u32 NEIGHBOR; // neighbor flag

  if (packetScanf(packet, "%t,%d,%d,%d,%d,%d", &ID, &TIME, &CALC, &CALC_VER,
      &VOTE, &NEIGHBOR) != 11)
    {
      logNormal("Inconsistent packet format for (r)esult packet.\n");
      return false;
    }

  if (arg)
    {
      R_PKT * PKT_R = (R_PKT*) arg;
      PKT_R->key.ID = ID;
      PKT_R->key.TIME = TIME;
      PKT_R->calc = CALC;
      PKT_R->calc_ver = CALC_VER;
      PKT_R->rslt = VOTE;
      PKT_R->neighbor = NEIGHBOR;
    }

  return true;
}
예제 #6
0
파일: suffrage.cpp 프로젝트: seato/suffrage
/*
 * Summary:     Handles (c)alculation packet reflex.  Packet information is saved
 *              and converted into a R packet to be forwarded to neighboring nodes.
 * Parameters:  (c)alculation packet.
 * Return:      None.
 */
void
c_handler(u8 * packet)
{
  C_PKT PKT_R;

  if (packetScanf(packet, "%Zc%z\n", C_ZScanner, &PKT_R) != 3)
    {
      logNormal("c_handler:  Failed at %d\n", packetCursor(packet));
      return;
    }

  if (PKT_R.calc < 0)
    {
      logNormal("c_handler:  Input %d must be a non-negative integer.\n",
          PKT_R.calc);
      return;
    }

  if (PKT_R.calc > PRIME_THRESHOLD)
    {
      logNormal("c_handler:  Value %d is higher than the threshold %d (%d).\n",
          PKT_R.calc, PRIME_THRESHOLD, PRIME_ARR_THRESHOLD - 1);
      return;
    }

  strikeCheck(); // evaluate the strikes for my neighbors
  flush(); // clear out my records for the new voting session

  R_PKT PKT_T; // synthesize a new packet
  ++HOST_CALC_VER;
  HOST_CALC = PKT_R.calc;
  PKT_T.key.ID = ID_HOST;
  PKT_T.key.TIME = millis();
  PKT_T.calc = HOST_CALC;
  PKT_T.calc_ver = HOST_CALC_VER;
  PKT_T.rslt = VOTE_NODE_ARR[0];

  // If all the hoops have been jumped through
  FWD_R_PKT(&PKT_T, packetSource(packet)); // Forward the packet
  voteCount(0, calculate(HOST_CALC)); // calculation occurs here

  return;
}
예제 #7
0
파일: suffrage.cpp 프로젝트: seato/suffrage
/*
 * Summary:     Given an array and a specific range [first, size) where the
 *              "size"_th iteration is not inclusive, return the index of the
 *              greatest positive value in the array or INVALID if there is a
 *              tie.
 * Parameters:  u32 array to search, u32 size of the array.
 * Return:      Index of the highest value greater than or equal to 0;
 *              INVALID otherwise.
 */
u32
getMaxIndex(u32 a[], u32 size)
{
  if (NULL == a) // null array pointer?
    {
      logNormal("getMaxIndex:  NULL array pointer!\n");
      API_ASSERT_NONNULL(a); // blinkcode!
    }

  if (size <= 0) // invalid size?
    {
      logNormal("getMaxIndex:  Invalid size %d\n", size);
      API_ASSERT_GREATER(size, 0); // blinkcode!
    }

  bool tiedetected = false; // flag to mark if there is a tie
  u32 maxVotes = 0; // highest amount of ballots currently
  u32 maxIndex = INVALID; // index of the highest candidate

  for (u32 i = 0; i < size; ++i)
    { // iterate through the entire array
      if (a[i] > maxVotes)
        { // record higher values
          maxVotes = a[i];
          maxIndex = i;
          tiedetected = false; // disarm tie flag
        }
      // if there is ever candidate that ties with the highest candidate
      else if (a[i] == maxVotes)
        tiedetected = true; // set tie flag
    }

  if (tiedetected) // if the tie flag was set
    return TIE; // there is no winning candidate

  // It worked, there's a candidate greater than 0 votes and no ties
  else if ((0 != maxVotes) && (INVALID != maxIndex))
    return maxIndex;

  else
    return INVALID; // This should never happen.
}
예제 #8
0
파일: suffrage.cpp 프로젝트: seato/suffrage
/*
 * Summary:     Displays a table containing each IXM's ID, timestamp(ms), and
 *              pings.  Note that there might exist a time-stamp inconsistency
 *              (boards may base their time based on when they started receiving
 *              power).
 * Parameters:  Time when function was called (handled automagically).
 * Return:      None.
 */
void
printTable(u32 when)
{
  if (when < 0)
    {
      logNormal("log:  No time-traveling or overflow allowed!\n");
      API_ASSERT_GREATER_EQUAL(when, 0); // blinkcode!
    }

  u32 HOST_TIME = when;

  facePrintf(
      TERMINAL_FACE,
      "\n\n\n\n\n\n\n\n\n\n\n\n\n+===============================================================+\n");
  facePrintf(TERMINAL_FACE,
      "|CALCULATION: %4d     HOST TIME: %010d                    |\n",
      HOST_CALC, HOST_TIME);
  facePrintf(TERMINAL_FACE,
      "+---------------------------------------------------------------+\n");
  facePrintf(TERMINAL_FACE,
      "|ID       ACTIVE     TIME-STAMP     VOTE       STRIKES     PINGS|\n");
  facePrintf(TERMINAL_FACE,
      "+----     ------     ----------     ------     -------     -----+\n");
  for (u32 i = 0; i < NODE_COUNT; ++i)
    {
      facePrintf(TERMINAL_FACE, "|%04t          %c%15d%11d%12d%10d|\n",
          ID_NODE_ARR[i], ACTIVE_NODE_ARR[i], TS_HOST_ARR[i], VOTE_NODE_ARR[i],
          STRIKES_NODE_ARR[i], PC_NODE_ARR[i]);
    }
  facePrintf(TERMINAL_FACE,
      "+---------------------------------------------------------------+\n");
  if ((TIE == MAJORITY_RSLT) || (INVALID == MAJORITY_RSLT) || (0
      == MAJORITY_RSLT))
    facePrintf(TERMINAL_FACE,
        "|MAJORITY: --                                                   |\n");
  else
    facePrintf(TERMINAL_FACE,
        "|MAJORITY: %4d                                                 |\n",
        MAJORITY_RSLT);
  facePrintf(TERMINAL_FACE,
      "+===============================================================+\n");

  // schedule the next table printout
  Alarms.set(Alarms.currentAlarmNumber(), when + printTable_PERIOD);

  return;
}
예제 #9
0
파일: suffrage.cpp 프로젝트: seato/suffrage
/*
 * Summary:     Custom (c)alculation packet scanner.
 * Parameters:  The arguments are automatically handled within a parent
 *              header file.
 * Return:      Boolean confirming the packet was read correctly.
 */
bool
C_ZScanner(u8 * packet, void * arg, bool alt, int width)
{
  /* (c)alculation packet structure */
  u32 CALC; // integer calculation

  if (packetScanf(packet, "%d", &CALC) != 1)
    {
      logNormal("Inconsistent packet format for (c)alculation packet.\n");

      return false;
    }

  if (arg)
    {
      C_PKT * PKT_R = (C_PKT*) arg;
      PKT_R->calc = CALC;
    }

  return true;
}
예제 #10
0
파일: ctexpcube.cpp 프로젝트: ctools/ctools
/***********************************************************************//**
 * @brief Generate the exposure cube(s).
 *
 * This method reads the task parameters from the parfile, sets up the
 * observation container, loops over all CTA observations in the container
 * and generates an exposure cube from the CTA observations.
 ***************************************************************************/
void ctexpcube::run(void)
{
    // If we're in debug mode then all output is also dumped on the screen
    if (logDebug()) {
        log.cout(true);
    }

    // Get task parameters
    get_parameters();

    // Warn if there are not enough energy bins
    log_string(TERSE, warn_too_few_energies(m_expcube.energies()));

    // Write input observation container into logger
    log_observations(NORMAL, m_obs, "Input observation");

    // Initialise exposure cube
    init_cube();

    // Write header into logger
    log_header1(TERSE, "Generate exposure cube");

    // Set pointer to logger dependent on chattiness
    GLog* logger = (logNormal()) ? &log : NULL;

    // Fill exposure cube
    m_expcube.fill(m_obs, logger);

    // Write exposure cube into logger
    log_string(EXPLICIT, m_expcube.print(m_chatter));

    // Optionally publish exposure cube
    if (m_publish) {
        publish();
    }

    // Return
    return;
}
예제 #11
0
파일: suffrage.cpp 프로젝트: seato/suffrage
/*
 * Summary:     Turns on a specific LED color depending on the status input.
 * Parameters:  u32 LED status denoting which LED to turn on.
 *              OFF = off, MINORITY = red, MAJORITY = green, PROCESSING = blue
 * Return:      None.
 */
void
setStatus(u32 STATUS)
{
  if ((STATUS != OFF) && // if input is not "no LED"
      (STATUS != MINORITY) && // or "red LED"
      (STATUS != MAJORITY) && // or "green LED"
      (STATUS != PROCESSING)) // or "blue LED"
    {
      logNormal("setStatus:  Invalid input %d\n", STATUS);
      // blinkcode!
      API_ASSERT((OFF == STATUS) || (MINORITY == STATUS)
          || (MAJORITY == STATUS) || (PROCESSING == STATUS), E_API_EQUAL);
    }

  for (u8 i = 0; i < 3; ++i)
    ledOff(LED_PIN[i]); // turn off the LEDs

  if (STATUS == OFF) // and if the status to display is "off"
    return; // keep the LEDs off

  ledOn(LED_PIN[STATUS]); // otherwise, turn on the appropriate LED

  return;
}
예제 #12
0
파일: ctlike.cpp 프로젝트: jdevin/ctools
/***********************************************************************//**
 * @brief Optimize model parameters using Levenberg-Marquardt method
 ***************************************************************************/
void ctlike::optimize_lm(void)
{
    // Write Header for optimization and indent for optimizer logging
    if (logTerse()) {
        log << std::endl;
        log.header1("Maximum likelihood optimisation");
        log.indent(1);
    }

    // Compute number of fitted parameters
    int nfit = 0;
    for (int i = 0; i < m_obs.models().size(); ++i) {
        const GModel* model = m_obs.models()[i];
        for (int k = 0; k < model->size(); ++k) {
            if ((*model)[k].is_free()) {
                nfit++;
            }
        }
    }

    // Notify if all parameters are fixed
    if (nfit == 0) {
        if (logTerse()) {
            log << "WARNING: All model parameters are fixed!";
            log << std::endl;
            log << "         ctlike will proceed without fitting parameters.";
            log << std::endl;
            log << "         All curvature matrix elements will be zero.";
            log << std::endl;
        }
    }

    // Perform LM optimization
    m_obs.optimize(*m_opt);

    // Optionally refit
    if (m_refit) {

        // Dump new header
        log.indent(0);
        if (logTerse()) {
            log << std::endl;
            log.header1("Maximum likelihood re-optimisation");
            log.indent(1);
        }

        // Optimise again
        m_obs.optimize(*m_opt);

    }

    // Optionally show curvature matrix
    if (logNormal()) {
        log << std::endl;
        log.header1("Curvature matrix");
        log.indent(1);
        log << *(const_cast<GObservations::likelihood&>(m_obs.function()).curvature());
        log << std::endl;
    }

    // Compute errors
    m_obs.errors(*m_opt);

    // Store maximum log likelihood value
    m_logL = -(m_opt->value());

    // Remove indent
    log.indent(0);

    // Return
    return;
}
예제 #13
0
파일: ctobssim.cpp 프로젝트: lyang54/ctools
/***********************************************************************//**
 * @brief Simulate source events from photon list
 *
 * @param[in] obs Pointer on CTA observation.
 * @param[in] models Model list.
 * @param[in] ran Random number generator.
 * @param[in] wrklog Pointer to logger.
 *
 * Simulate source events from a photon list for a given CTA observation.
 * The events are stored in as event list in the observation.
 *
 * This method does nothing if the observation pointer is NULL. It also
 * verifies if the observation has a valid pointing and response.
 ***************************************************************************/
void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models,
                               GRan& ran, GLog* wrklog)
{
    // Continue only if observation pointer is valid
    if (obs != NULL) {

        // If no logger is specified then use the default logger
        if (wrklog == NULL) {
            wrklog = &log;
        }

        // Get CTA response
        const GCTAResponseIrf* rsp =
            dynamic_cast<const GCTAResponseIrf*>(obs->response());
        if (rsp == NULL) {
            std::string msg = "Response is not an IRF response.\n" +
                              obs->response()->print();
            throw GException::invalid_value(G_SIMULATE_SOURCE, msg);
        }

        // Get pointer on event list (circumvent const correctness)
        GCTAEventList* events =
            static_cast<GCTAEventList*>(const_cast<GEvents*>(obs->events()));

        // Extract simulation region.
        GSkyDir dir = events->roi().centre().dir();
        double  rad = events->roi().radius() + g_roi_margin;

        // Dump simulation cone information
        if (logNormal()) {
            *wrklog << gammalib::parformat("Simulation area");
            *wrklog << m_area << " cm2" << std::endl;
            *wrklog << gammalib::parformat("Simulation cone");
            *wrklog << "RA=" << dir.ra_deg() << " deg";
            *wrklog << ", Dec=" << dir.dec_deg() << " deg";
            *wrklog << ", r=" << rad << " deg" << std::endl;
        }

        // Initialise indentation for logging
        int indent = 0;

        // Loop over all Good Time Intervals
        for (int it = 0; it < events->gti().size(); ++it) {

            // Extract time interval
            GTime tmin = events->gti().tstart(it);
            GTime tmax = events->gti().tstop(it);

            // Dump time interval
            if (logNormal()) {
                if (events->gti().size() > 1) {
                    indent++;
                    wrklog->indent(indent);
                }
                *wrklog << gammalib::parformat("Time interval", indent);
                *wrklog << tmin.convert(m_cta_ref);
                *wrklog << " - ";
                *wrklog << tmax.convert(m_cta_ref);
                *wrklog << " s" << std::endl;
            }

            // Loop over all energy boundaries
            for (int ie = 0; ie <  events->ebounds().size(); ++ie) {

                // Extract energy boundaries
                GEnergy emin = events->ebounds().emin(ie);
                GEnergy emax = events->ebounds().emax(ie);

                // Set true photon energy limits for simulation. If observation
                // has energy dispersion then add margin
                GEnergy e_true_min = emin;
                GEnergy e_true_max = emax;
                if (rsp->use_edisp()) {
                    e_true_min = rsp->ebounds(e_true_min).emin();
                    e_true_max = rsp->ebounds(e_true_max).emax();
                }

                // Dump energy range
                if (logNormal()) {
                    if (events->ebounds().size() > 1) {
                        indent++;
                        wrklog->indent(indent);
                    }
                    *wrklog << gammalib::parformat("Photon energy range", indent);
                    *wrklog << e_true_min << " - " << e_true_max << std::endl;
                    *wrklog << gammalib::parformat("Event energy range", indent);
                    *wrklog << emin << " - " << emax << std::endl;
                }

                // Loop over all sky models
                for (int i = 0; i < models.size(); ++i) {

                    // Get sky model (NULL if not a sky model)
                    const GModelSky* model =
                          dynamic_cast<const GModelSky*>(models[i]);

                    // If we have a sky model that applies to the present
                    // observation then simulate events
                    if (model != NULL &&
                        model->is_valid(obs->instrument(), obs->id())) {

                        // Determine duration of a time slice by limiting the
                        // number of simulated photons to m_max_photons.
                        // The photon rate is estimated from the model flux
                        // and used to set the duration of the time slice.
                        double flux     = get_model_flux(model, emin, emax,
                                                         dir, rad);
                        double rate     = flux * m_area;
                        double duration = 1800.0;  // default: 1800 sec
                        if (rate > 0.0) {
                            duration = m_max_photons / rate;
                            if (duration < 1.0) {  // not <1 sec
                                duration = 1.0;
                            }
                            else if (duration > 180000.0) { // not >50 hr
                                duration = 180000.0;
                            }
                        }
                        GTime tslice(duration, "sec");

                        // If photon rate exceeds the maximum photon rate
                        // then throw an exception
                        if (rate > m_max_rate) {
                            std::string modnam = (model->name().length() > 0) ?
                                                 model->name() : "Unknown";
                            std::string msg    = "Photon rate "+
                                                 gammalib::str(rate)+
                                                 " photons/sec for model \""+
                                                 modnam+"\" exceeds maximum"
                                                 " allowed photon rate of "+
                                                 gammalib::str(m_max_rate)+
                                                 " photons/sec. Please check"
                                                 " the model parameters for"
                                                 " model \""+modnam+"\" or"
                                                 " increase the value of the"
                                                 " hidden \"maxrate\""
                                                 " parameter.";
                            throw GException::invalid_value(G_SIMULATE_SOURCE, msg);
                        }

                        // Dump length of time slice and rate
                        if (logExplicit()) {
                            *wrklog << gammalib::parformat("Photon rate", indent);
                            *wrklog << rate << " photons/sec";
                            if (model->name().length() > 0) {
                                *wrklog << " [" << model->name() << "]";
                            }
                            *wrklog << std::endl;
                        }

                        // To reduce memory requirements we split long time
                        // intervals into several slices.
                        GTime tstart = tmin;
                        GTime tstop  = tstart + tslice;

                        // Initialise cumulative photon counters
                        int nphotons = 0;

                        // Loop over time slices
                        while (tstart < tmax) {

                            // Make sure that tstop <= tmax
                            if (tstop > tmax) {
                                tstop = tmax;
                            }

                            // Dump time slice
                            if (logExplicit()) {
                                if (tmax - tmin > tslice) {
                                    indent++;
                                    wrklog->indent(indent);
                                }
                                *wrklog << gammalib::parformat("Time slice", indent);
                                *wrklog << tstart.convert(m_cta_ref);
                                *wrklog << " - ";
                                *wrklog << tstop.convert(m_cta_ref);
                                *wrklog << " s";
                                if (model->name().length() > 0) {
                                    *wrklog << " [" << model->name() << "]";
                                }
                                *wrklog << std::endl;
                            }

                            // Get photons
                            GPhotons photons = model->mc(m_area, dir, rad,
                                                         e_true_min, e_true_max,
                                                         tstart, tstop, ran);

                            // Dump number of simulated photons
                            if (logExplicit()) {
                                *wrklog << gammalib::parformat("MC source photons/slice", indent);
                                *wrklog << photons.size();
                                if (model->name().length() > 0) {
                                    *wrklog << " [" << model->name() << "]";
                                }
                                *wrklog << std::endl;
                            }

                            // Simulate events from photons
                            for (int i = 0; i < photons.size(); ++i) {

                                // Increment photon counter
                                nphotons++;

                                // Simulate event. Note that this method
                                // includes the deadtime correction.
                                GCTAEventAtom* event = rsp->mc(m_area,
                                                               photons[i],
                                                               *obs,
                                                               ran);

                                if (event != NULL) {

                                    // Use event only if it falls within ROI
                                    // energy boundary and time slice
                                    if (events->roi().contains(*event) &&
                                        event->energy() >= emin &&
                                        event->energy() <= emax &&
                                        event->time() >= tstart &&
                                        event->time() <= tstop) {
                                        event->event_id(m_event_id);
                                        events->append(*event);
                                        m_event_id++;
                                    }
                                    delete event;
                                }

                            } // endfor: looped over events

                            // Go to next time slice
                            tstart = tstop;
                            tstop  = tstart + tslice;

                            // Reset indentation
                            if (logExplicit()) {
                                if (tmax - tmin > tslice) {
                                    indent--;
                                    wrklog->indent(indent);
                                }
                            }

                        } // endwhile: looped over time slices

                        // Dump simulation results
                        if (logNormal()) {
                            *wrklog << gammalib::parformat("MC source photons", indent);
                            *wrklog << nphotons;
                            if (model->name().length() > 0) {
                                *wrklog << " [" << model->name() << "]";
                            }
                            *wrklog << std::endl;
                            *wrklog << gammalib::parformat("MC source events", indent);
                            *wrklog << events->size();
                            if (model->name().length() > 0) {
                                *wrklog << " [" << model->name() << "]";
                            }
                            *wrklog << std::endl;

                        }

                    } // endif: model was a sky model

                } // endfor: looped over models

                // Dump simulation results
                if (logNormal()) {
                    *wrklog << gammalib::parformat("MC source events", indent);
                    *wrklog << events->size();
                    *wrklog << " (all source models)";
                    *wrklog << std::endl;
                }

                // Reset indentation
                if (logNormal()) {
                    if (events->ebounds().size() > 1) {
                        indent--;
                        wrklog->indent(indent);

                    }
                }

            } // endfor: looped over all energy boundaries

            // Reset indentation
            if (logNormal()) {
                if (events->gti().size() > 1) {
                    indent--;
                    wrklog->indent(indent);
                }
            }

        } // endfor: looped over all time intervals

        // Reset indentation
        wrklog->indent(0);

    } // endif: observation pointer was valid

    // Return
    return;
}
예제 #14
0
파일: ctobssim.cpp 프로젝트: lyang54/ctools
/***********************************************************************//**
 * @brief Simulate event data
 *
 * This method runs the simulation. Results are not saved by this method.
 * Invoke "save" to save the results.
 ***************************************************************************/
void ctobssim::run(void)
{
    // Switch screen logging on in debug mode
    if (logDebug()) {
        log.cout(true);
    }

    // Get parameters
    get_parameters();

    // Write input parameters into logger
    if (logTerse()) {
        log_parameters();
        log << std::endl;
    }

    // Special mode: if read ahead is specified we know that we called
    // the execute() method, hence files are saved immediately and event
    // lists are disposed afterwards.
    if (read_ahead()) {
        m_save_and_dispose = true;
    }

    // Determine the number of valid CTA observations, set energy dispersion flag
    // for all CTA observations and save old values in save_edisp vector
    int               n_observations = 0;
    std::vector<bool> save_edisp;
    save_edisp.assign(m_obs.size(), false);
    for (int i = 0; i < m_obs.size(); ++i) {
        GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[i]);
        if (obs != NULL) {
            save_edisp[i] = obs->response()->apply_edisp();
            obs->response()->apply_edisp(m_apply_edisp);
            n_observations++;
        }
    }

    // If more than a single observation has been handled then make sure that
    // an XML file will be used for storage
    if (n_observations > 1) {
        m_use_xml = true;
    }

    // Write execution mode into logger
    if (logTerse()) {
        log << std::endl;
        log.header1("Execution mode");
        log << gammalib::parformat("Event list management");
        if (m_save_and_dispose) {
            log << "Save and dispose (reduces memory needs)" << std::endl;
        }
        else {
            log << "Keep events in memory" << std::endl;
        }
        log << gammalib::parformat("Output format");
        if (m_use_xml) {
            log << "Write Observation Definition XML file" << std::endl;
        }
        else {
            log << "Write single event list FITS file" << std::endl;
        }
    }

    // Write seed values into logger
    if (logTerse()) {
        log << std::endl;
        log.header1("Seed values");
        for (int i = 0; i < m_rans.size(); ++i) {
            log << gammalib::parformat("Seed "+gammalib::str(i));
            log << gammalib::str(m_rans[i].seed()) << std::endl;
        }
    }

    // Write observation(s) into logger
    if (logTerse()) {
        log << std::endl;
        if (m_obs.size() > 1) {
            log.header1("Observations");
        }
        else {
            log.header1("Observation");
        }
        log << m_obs << std::endl;
    }

    // Write header
    if (logTerse()) {
        log << std::endl;
        if (m_obs.size() > 1) {
            log.header1("Simulate observations");
        }
        else {
            log.header1("Simulate observation");
        }
    }

    // From here on the code can be parallelized if OpenMP support
    // is enabled. The code in the following block corresponds to the
    // code that will be executed in each thread
    #pragma omp parallel
    {
        // Each thread will have it's own logger to avoid conflicts
        GLog wrklog;
        if (logDebug()) {
            wrklog.cout(true);
        }

        // Allocate and initialize copies for multi-threading
        GModels models(m_obs.models());

        // Copy configuration from application logger to thread logger
        wrklog.date(log.date());
        wrklog.name(log.name());

        // Set a big value to avoid flushing
        wrklog.max_size(10000000);

        // Loop over all observation in the container. If OpenMP support
        // is enabled, this loop will be parallelized.
        #pragma omp for
        for (int i = 0; i < m_obs.size(); ++i) {

            // Get pointer on CTA observation
            GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[i]);

            // Continue only if observation is a CTA observation
            if (obs != NULL) {

                // Write header for observation
                if (logTerse()) {
                    if (obs->name().length() > 1) {
                        wrklog.header3("Observation "+obs->name());
                    }
                    else {
                        wrklog.header3("Observation");
                    }
                }

                // Work on a clone of the CTA observation. This makes sure that
                // any memory allocated for computing (for example a response
                // cache) is properly de-allocated on exit of this run
                GCTAObservation obs_clone = *obs;

                // Save number of events before entering simulation
                int events_before = obs_clone.events()->size();

                // Simulate source events
                simulate_source(&obs_clone, models, m_rans[i], &wrklog);

                // Simulate source events
                simulate_background(&obs_clone, models, m_rans[i], &wrklog);

                // Dump simulation results
                if (logNormal()) {
                    wrklog << gammalib::parformat("MC events");
                    wrklog << obs_clone.events()->size() - events_before;
                    wrklog << " (all models)";
                    wrklog << std::endl;
                }

                // Append the event list to the original observation
                obs->events(*(obs_clone.events()));

                // If requested, event lists are saved immediately
                if (m_save_and_dispose) {

                    // Set event output file name. If multiple observations are
                    // handled, build the filename from prefix and observation
                    // index. Otherwise use the outfile parameter.
                    std::string outfile;
                    if (m_use_xml) {
                        m_prefix = (*this)["prefix"].string();
                        outfile  = m_prefix + gammalib::str(i) + ".fits";
                    }
                    else {
                        outfile  = (*this)["outevents"].filename();
                    }

                    // Store output file name in original observation
                    obs->eventfile(outfile);

                    // Save observation into FITS file. This is a critical zone
                    // to avoid multiple threads writing simultaneously
                    #pragma omp critical
                    {
                        obs_clone.save(outfile, clobber());
                    }

                    // Dispose events
                    obs->dispose_events();

                }

                // ... otherwise append the event list to the original observation
                /*
                else {
                    obs->events(*(obs_clone.events()));
                }
                */

            } // endif: CTA observation found

        } // endfor: looped over observations

        // At the end, the content of the thread logger is added to
        // the application logger
        #pragma omp critical (log)
        {
            log << wrklog;
        }

    } // end pragma omp parallel

    // Restore energy dispersion flag for all CTA observations
    for (int i = 0; i < m_obs.size(); ++i) {
        GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[i]);
        if (obs != NULL) {
            obs->response()->apply_edisp(save_edisp[i]);
        }
    }

    // Return
    return;
}
예제 #15
0
파일: ctobssim.cpp 프로젝트: lyang54/ctools
/***********************************************************************//**
 * @brief Simulate background events from model
 *
 * @param[in] obs Pointer on CTA observation.
 * @param[in] models Models.
 * @param[in] ran Random number generator.
 * @param[in] wrklog Pointer to logger.
 *
 * Simulate background events from models. The events are stored as event
 * list in the observation.
 *
 * This method does nothing if the observation pointer is NULL.
 ***************************************************************************/
void ctobssim::simulate_background(GCTAObservation* obs,
                                   const GModels&   models,
                                   GRan&            ran,
                                   GLog*            wrklog)
{
    // Continue only if observation pointer is valid
    if (obs != NULL) {

        // If no logger is specified then use the default logger
        if (wrklog == NULL) {
            wrklog = &log;
        }

        // Get pointer on event list (circumvent const correctness)
        GCTAEventList* events =
            static_cast<GCTAEventList*>(const_cast<GEvents*>(obs->events()));

        // Loop over all models
        for (int i = 0; i < models.size(); ++i) {

            // Get data model (NULL if not a data model)
            const GModelData* model =
                dynamic_cast<const GModelData*>(models[i]);

            // If we have a data model that applies to the present observation
            // then simulate events
            if (model != NULL &&
                model->is_valid(obs->instrument(), obs->id())) {

                // Get simulated CTA event list. Note that this method
                // includes the deadtime correction.
                GCTAEventList* list =
                     dynamic_cast<GCTAEventList*>(model->mc(*obs, ran));

                // Continue only if we got a CTA event list
                if (list != NULL) {

                    // Reserves space for events
                    events->reserve(list->size()+events->size());

                    // Append events
                    for (int k = 0; k < list->size(); k++) {

                        // Get event pointer
                        GCTAEventAtom* event = (*list)[k];

                        // Use event only if it falls within ROI
                        if (events->roi().contains(*event)) {

                            // Set event identifier
                            event->event_id(m_event_id);
                            m_event_id++;

                            // Append event
                            events->append(*event);

                        } // endif: event was within ROI

                    } // endfor: looped over all events

                    // Dump simulation results
                    if (logNormal()) {
                        *wrklog << gammalib::parformat("MC background events");
                        *wrklog << list->size() << std::endl;
                    }

                    // Free event list
                    delete list;

                } // endif: we had a CTA event list

            } // endif: model was valid

        } // endfor: looped over all models

    } // endif: observation pointer was valid

    // Return
    return;
}
예제 #16
0
/***********************************************************************//**
 * @brief Simulate source events from photon list
 *
 * @param[in] obs Pointer on CTA observation.
 * @param[in] models Model list.
 * @param[in] ran Random number generator.
 * @param[in] wrklog Pointer to logger.
 *
 * Simulate source events from a photon list for a given CTA observation.
 * The events are stored in as event list in the observation.
 *
 * This method does nothing if the observation pointer is NULL. It also
 * verifies if the observation has a valid pointing and response.
 ***************************************************************************/
void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models,
                               GRan& ran, GLog* wrklog)
{
    // Continue only if observation pointer is valid
    if (obs != NULL) {

        // If no logger is specified then use the default logger
        if (wrklog == NULL) {
            wrklog = &log;
        }

        // Get pointer on CTA response. Throw an exception if the response
        // is not defined.
        const GCTAResponse& rsp = obs->response();

        // Make sure that the observation holds a CTA event list. If this
        // is not the case then allocate and attach a CTA event list now.
        if (dynamic_cast<const GCTAEventList*>(obs->events()) == NULL) {
            set_list(obs);
        }

        // Get pointer on event list (circumvent const correctness)
        GCTAEventList* events = static_cast<GCTAEventList*>(const_cast<GEvents*>(obs->events()));

        // Extract simulation region.
        GSkyDir dir = events->roi().centre().dir();
        double  rad = events->roi().radius() + g_roi_margin;

        // Dump simulation cone information
        if (logNormal()) {
            *wrklog << gammalib::parformat("Simulation area");
            *wrklog << m_area << " cm2" << std::endl;
            *wrklog << gammalib::parformat("Simulation cone");
            *wrklog << "RA=" << dir.ra_deg() << " deg";
            *wrklog << ", Dec=" << dir.dec_deg() << " deg";
            *wrklog << ", r=" << rad << " deg" << std::endl;
        }

        // Initialise indentation for logging
        int indent = 0;

        // Loop over all Good Time Intervals
        for (int it = 0; it < events->gti().size(); ++it) {

            // Extract time interval
            GTime tmin = events->gti().tstart(it);
            GTime tmax = events->gti().tstop(it);

            // Dump time interval
            if (logNormal()) {
                if (events->gti().size() > 1) {
                    indent++;
                    wrklog->indent(indent);
                }
                *wrklog << gammalib::parformat("Time interval", indent);
                *wrklog << tmin.convert(m_cta_ref);
                *wrklog << " - ";
                *wrklog << tmax.convert(m_cta_ref);
                *wrklog << " s" << std::endl;
            }

            // Loop over all energy boundaries
            for (int ie = 0; ie <  events->ebounds().size(); ++ie) {

                // Extract energy boundaries
                GEnergy emin = events->ebounds().emin(ie);
                GEnergy emax = events->ebounds().emax(ie);

                // Dump energy range
                if (logNormal()) {
                    if (events->ebounds().size() > 1) {
                        indent++;
                        wrklog->indent(indent);
                    }
                    *wrklog << gammalib::parformat("Energy range", indent);
                    *wrklog << emin << " - " << emax << std::endl;
                }

                // Loop over all sky models
                for (int i = 0; i < models.size(); ++i) {

                    // Get sky model (NULL if not a sky model)
                    const GModelSky* model =
                          dynamic_cast<const GModelSky*>(models[i]);

                    // If we have a sky model that applies to the present
                    // observation then simulate events
                    if (model != NULL &&
                        model->is_valid(obs->instrument(), obs->id())) {

                        // Determine duration of a time slice by limiting the
                        // number of simulated photons to m_max_photons.
                        // The photon rate is estimated from the model flux
                        // and used to set the duration of the time slice.
                        double flux     = model->spectral()->flux(emin, emax);
                        double rate     = flux * m_area;
                        double duration = 1800.0;  // default: 1800 sec
                        if (rate > 0.0) {
                            duration = m_max_photons / rate;
                            if (duration < 1.0) {  // not <1 sec
                                duration = 1.0;
                            }
                            else if (duration > 180000.0) { // not >50 hr
                                duration = 180000.0;
                            }
                        }
                        GTime tslice(duration, "sec");

                        // To reduce memory requirements we split long time
                        // intervals into several slices.
                        GTime tstart = tmin;
                        GTime tstop  = tstart + tslice;

                        // Initialise cumulative photon counters
                        int nphotons = 0;

                        // Loop over time slices
                        while (tstart < tmax) {

                            // Make sure that tstop <= tmax
                            if (tstop > tmax) {
                                tstop = tmax;
                            }

                            // Dump time slice
                            if (logExplicit()) {
                                if (tmax - tmin > tslice) {
                                    indent++;
                                    wrklog->indent(indent);
                                }
                                *wrklog << gammalib::parformat("Time slice", indent);
                                *wrklog << tstart.convert(m_cta_ref);
                                *wrklog << " - ";
                                *wrklog << tstop.convert(m_cta_ref);
                                *wrklog << " s" << std::endl;
                            }

                            // Get photons
                            GPhotons photons = model->mc(m_area, dir, rad,
                                                         emin, emax,
                                                         tstart, tstop, ran);

                            // Dump number of simulated photons
                            if (logExplicit()) {
                                *wrklog << gammalib::parformat("MC source photons/slice", indent);
                                *wrklog << photons.size();
                                if (model->name().length() > 0) {
                                    *wrklog << " [" << model->name() << "]";
                                }
                                *wrklog << std::endl;
                            }

                            // Simulate events from photons
                            for (int i = 0; i < photons.size(); ++i) {

                                // Increment photon counter
                                nphotons++;

                                // Simulate event. Note that this method
                                // includes the deadtime correction.
                                GCTAEventAtom* event = rsp.mc(m_area,
                                                              photons[i],
                                                              *obs,
                                                              ran);
                                if (event != NULL) {

                                    // Use event only if it falls within ROI
                                    if (events->roi().contains(*event)) {
                                        event->event_id(m_event_id);
                                        events->append(*event);
                                        m_event_id++;
                                    }
                                    delete event;
                                }

                            } // endfor: looped over events

                            // Go to next time slice
                            tstart = tstop;
                            tstop  = tstart + tslice;

                            // Reset indentation
                            if (logExplicit()) {
                                if (tmax - tmin > tslice) {
                                    indent--;
                                    wrklog->indent(indent);
                                }
                            }

                        } // endwhile: looped over time slices

                        // Dump simulation results
                        if (logNormal()) {
                            *wrklog << gammalib::parformat("MC source photons", indent);
                            *wrklog << nphotons;
                            if (model->name().length() > 0) {
                                *wrklog << " [" << model->name() << "]";
                            }
                            *wrklog << std::endl;
                            *wrklog << gammalib::parformat("MC source events", indent);
                            *wrklog << events->size();
                            if (model->name().length() > 0) {
                                *wrklog << " [" << model->name() << "]";
                            }
                            *wrklog << std::endl;

                        }

                    } // endif: model was a sky model

                } // endfor: looped over models

                // Dump simulation results
                if (logNormal()) {
                    *wrklog << gammalib::parformat("MC source events", indent);
                    *wrklog << events->size();
                    *wrklog << " (all source models)";
                    *wrklog << std::endl;
                }

                // Reset indentation
                if (logNormal()) {
                    if (events->ebounds().size() > 1) {
                        indent--;
                        wrklog->indent(indent);

                    }
                }

            } // endfor: looped over all energy boundaries

            // Reset indentation
            if (logNormal()) {
                if (events->gti().size() > 1) {
                    indent--;
                    wrklog->indent(indent);
                }
            }

        } // endfor: looped over all time intervals

        // Reset indentation
        wrklog->indent(0);

    } // endif: observation pointer was valid

    // Return
    return;
}
예제 #17
0
/***********************************************************************//**
 * @brief Simulate event data
 *
 * This method runs the simulation. Results are not saved by this method.
 * Invoke "save" to save the results.
 ***************************************************************************/
void ctobssim::run(void)
{
    // Switch screen logging on in debug mode
    if (logDebug()) {
        log.cout(true);
    }

    // Get parameters
    get_parameters();

    // Write input parameters into logger
    if (logTerse()) {
        log_parameters();
        log << std::endl;
    }

    // Write seed values into logger
    if (logTerse()) {
        log << std::endl;
        log.header1("Seed values");
        for (int i = 0; i < m_rans.size(); ++i) {
            log << gammalib::parformat("Seed "+gammalib::str(i));
            log << gammalib::str(m_rans[i].seed()) << std::endl;
        }
    }

    // Write observation(s) into logger
    if (logTerse()) {
        log << std::endl;
        if (m_obs.size() > 1) {
            log.header1("Observations");
        }
        else {
            log.header1("Observation");
        }
        log << m_obs << std::endl;
    }

    // Write header
    if (logTerse()) {
        log << std::endl;
        if (m_obs.size() > 1) {
            log.header1("Simulate observations");
        }
        else {
            log.header1("Simulate observation");
        }
    }

    // Initialise counters
    int n_observations = 0;

    // From here on the code can be parallelized if OpenMP support
    // is enabled. The code in the following block corresponds to the
    // code that will be executed in each thread
    #pragma omp parallel
    {
        // Each thread will have it's own logger to avoid conflicts
        GLog wrklog;
        if (logDebug()) {
            wrklog.cout(true);
        }

        // Copy configuration from application logger to thread logger
        wrklog.date(log.date());
        wrklog.name(log.name());

        // Set a big value to avoid flushing
        wrklog.max_size(10000000);

        // Loop over all observation in the container. If OpenMP support
        // is enabled, this looped will be parallelized.
        #pragma omp for
        for (int i = 0; i < m_obs.size(); ++i) {

            // Get CTA observation
            GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[i]);

            // Continue only if observation is a CTA observation
            if (obs != NULL) {

                // Write header for observation
                if (logTerse()) {
                    if (obs->name().length() > 1) {
                        wrklog.header3("Observation "+obs->name());
                    }
                    else {
                        wrklog.header3("Observation");
                    }
                }

                // Increment counter
                n_observations++;

                // Save number of events before entering simulation
                int events_before = obs->events()->size();

                // Simulate source events
                simulate_source(obs, m_obs.models(), m_rans[i], &wrklog);

                // Simulate source events
                simulate_background(obs, m_obs.models(), m_rans[i], &wrklog);

                // Dump simulation results
                if (logNormal()) {
                    wrklog << gammalib::parformat("MC events");
                    wrklog << obs->events()->size() - events_before;
                    wrklog << " (all models)";
                    wrklog << std::endl;
                }


            } // endif: CTA observation found

        } // endfor: looped over observations

        // At the end, the content of the thread logger is added to
        // the application logger
        #pragma omp critical (log)
        {
            log << wrklog;
        }

    } // end pragma omp parallel
    
    // If more than a single observation has been handled then make sure that
    // an XML file will be used for storage
    if (n_observations > 1) {
        m_use_xml = true;
    }

    // Return
    return;
}
예제 #18
0
T& Random< T, G, I, F >::logNormal(T &t, F m, F s) {
  return const_cast< T& >(logNormal(const_cast< const T& >(t), m, s));
}
예제 #19
0
// Returns 0 iff no measurement taken, 1 if a valid measurement was found, -1 if observed to be empty
template <typename PointT, typename NormalT> int
cpu_tsdf::TSDFVolumeOctree::updateVoxel (
    const cpu_tsdf::OctreeNode::Ptr &voxel, 
    const pcl::PointCloud<PointT> &cloud, 
    const pcl::PointCloud<NormalT> &normals, 
    const Eigen::Affine3f &trans_inv)
{
  // assert (!voxel->hasChildren ());

  if (voxel->hasChildren ())
  {
    std::vector<OctreeNode::Ptr>& children = voxel->getChildren ();
    std::vector<bool> is_empty (children.size ());
//#pragma omp parallel for
    for (size_t i = 0; i < children.size (); i++)
    {
      is_empty[i] = updateVoxel (children[i], cloud, normals, trans_inv) < 0;
    }
    bool all_are_empty = true;
    for (size_t i = 0; i < is_empty.size (); i++)
      all_are_empty &= is_empty[i];
    if (all_are_empty)
    {
      children.clear (); // Remove empty voxels
    }
    else
    {
      return (1); // Say I am not empty
    }
  }
  pcl::PointXYZ v_g_orig;
  voxel->getCenter (v_g_orig.x, v_g_orig.y, v_g_orig.z);
  pcl::PointXYZ v_g = pcl::transformPoint (v_g_orig, trans_inv);
  if (v_g.z < min_sensor_dist_ || v_g.z > max_sensor_dist_)
    return (0); // No observation
  int u, v;
  if (!reprojectPoint (v_g, u, v))
    return (0); // No observation
  const PointT &pt = cloud (u,v);
  if (pcl_isnan (pt.z))
    return (0); // No observation
   // if (pt.z >= max_sensor_dist_) // We want to let empty points be empty, even at noisy readings
   //   return (0);
  float d;
  float w;
  voxel->getData (d, w);
  float d_new = (pt.z - v_g.z);
  // Check if we can split
  if (fabs (d_new) < 3*voxel->getMaxSize ()/4.)// || (fabs (d_new) < max_dist_))  
  {
    float xsize, ysize, zsize;
    voxel->getSize (xsize, ysize, zsize);
    if (xsize > xsize_ / xres_ && ysize > ysize_ / yres_ && zsize > zsize_ / zres_)
    {
      std::vector<OctreeNode::Ptr>& children = voxel->split ();
      std::vector<bool> is_empty (children.size ());
//#pragma omp parallel for
      for (size_t i = 0; i < children.size (); i++)
      {
        // TODO Make the weight and distance match the parent's?
        // children[i]->setData (d, w);
        is_empty[i] = updateVoxel (children[i], cloud, normals, trans_inv) < 0;
      }
      bool all_are_empty = true;
      for (size_t i = 0; i < is_empty.size (); i++)
        all_are_empty &= is_empty[i];
      if (all_are_empty)
      {
        children.clear (); // Remove empty voxel
      }
      else
      {
        return (1); // Say I am not empty
      }
    }
  }
  if (d_new > max_dist_pos_)
  {
    d_new = max_dist_pos_;
  }
  else if (d_new < -max_dist_neg_)
  {
    return (0); // No observation, effectively
  }
  // Normalize s.t. -1 = unobserved
  d_new /= max_dist_neg_;

  float w_new = 1;
  if (weight_by_depth_)
    w_new *= (1 - std::min(pt.z / 10., 1.)); // Scales s.t. at 10m it's worthless
  if (weight_by_variance_ && voxel->nsample_ > 5)
    w_new *= std::exp (logNormal (d_new, voxel->d_, voxel->getVariance ()));
  if (integrate_color_)
    voxel->addObservation (d_new, w_new, max_weight_, pt.r, pt.g, pt.b);
  else
    voxel->addObservation (d_new, w_new, max_weight_);
  if (voxel->d_ < -0.99)
    return (0);
  else if (voxel->d_ < 0.99* max_dist_pos_ / max_dist_neg_) //if I am not empty
    return (1); // Say so
  else
    return (-1); // Otherwise say I'm empty
  
  
  
}
예제 #20
0
void Gui::SetArm(const char* text)
{	
	//Initialize a surface used to hide a part of the screen wich is used later
	SDL_Surface* hide = NULL;
	hide=LoadImage("Images/hide.png");

	//The variables that the window is going to get

	double mean =0;//the mean of the arm
	double variance =0;//its variance
	char armType ='A';//its type

	//Initializing the texts
	Texts arm(0,150,_font,text,_textColor);	
	Texts instructions(0,250,_font2,"Choose a type of arm then click in the boxes and type the parameters",_textColor);
	//Initializing the buttons

	//Ok button to skip to the next window
	Buttons ok(361,500, "Images/ok1.png", "Images/ok2.png","Images/ok3.png");

	//Type zones for the mean and the variance
	TypeZone meanT(300,400,_font2,"Mean",_textColor);	
	TypeZone varianceT(600,400,_font2,"Variance",_textColor);
	

	//Radiobuttons to choose the type of arm (exponential, uniform real, uniform int, poisson, logNormal)
	RadioButtons exp(100,300,"Exponential",_font2,_textColor);
	RadioButtons unifr(exp.GetBox().x+exp.GetBox().w+20,300,"Uniform real",_font2,_textColor);
	RadioButtons unifi(unifr.GetBox().x+unifr.GetBox().w+20,300,"Uniform int",_font2,_textColor);
	RadioButtons poisson(unifi.GetBox().x+unifi.GetBox().w+20,300,"Poisson",_font2,_textColor);
	RadioButtons logNormal(poisson.GetBox().x+poisson.GetBox().w+20,300,"Log-normal",_font2,_textColor);

	//Calculate the x for centering them (width of the screen minus the sum the width of the buttons)

	int xCentered = ((*(_screen.GetScreen())).clip_rect.w-exp.GetBox().w-unifr.GetBox().w-unifi.GetBox().w-poisson.GetBox().w-logNormal.GetBox().w-80)/2;

	//Relocate the buttons

	exp.SetPosition(xCentered,exp.GetBox().y);
	unifr.SetPosition(exp.GetBox().x+exp.GetBox().w+20,unifr.GetBox().y);
	unifi.SetPosition(unifr.GetBox().x+unifr.GetBox().w+20,unifi.GetBox().y);
	poisson.SetPosition(unifi.GetBox().x+unifi.GetBox().w+20,poisson.GetBox().y);
	logNormal.SetPosition(poisson.GetBox().x+poisson.GetBox().w+20,logNormal.GetBox().y);

	//Display them all

	arm.DisplayCentered(_screen);
	instructions.DisplayCentered(_screen);
	//meanT.Display(_screen);

	
	
	ok.Show(_screen);
	exp.Show(_screen);
	unifr.Show(_screen);
	unifi.Show(_screen);
	poisson.Show(_screen);
	logNormal.Show(_screen);

	
	meanT.DisplayLeft(_screen,mean,_font2,_textColor);
	varianceT.DisplayRight(_screen,mean,_font2,_textColor);
	
	
	
		//Initialize the event structure
	SDL_Event event;

	//Initialization of the loop
	bool isChoiceCorrect= false;
	bool skip=false;
	while((skip==false)&&(_quit==false))
	{	//While there's an event to handle
		while( SDL_PollEvent( &event ) )
			{	
				//the buttons react to the user's actions 
				ok.HandleEvents(event);
				exp.HandleEvents(event);
				unifr.HandleEvents(event);
				unifi.HandleEvents(event);
				poisson.HandleEvents(event);
				logNormal.HandleEvents(event);

				meanT.HandleEvents(event,mean);
				
				
				//For some button we just need the mean to set the distribution so in this case we hide the variance
				if((exp.IsActive()==false)&&(poisson.IsActive()==false))
				{				
				varianceT.HandleEvents(event,variance);
				
				}
				//we check if one option was chosen
				isChoiceCorrect = (exp.IsActive()|| unifr.IsActive()||unifi.IsActive()||poisson.IsActive()||logNormal.IsActive());

				//If the user clicks on ok and made a choice 
				if((ok.HandleEvents(event)==false)&&(isChoiceCorrect))
				{
					//skip to the next window
				skip=true;
				}

				//If he clicks on ok and hasn't made a choice then change color of the text
				if((ok.HandleEvents(event)==false)&&(isChoiceCorrect==false))
				{
					SDL_Color red={240,0,0};
					exp.SetColor(red);
					unifr.SetColor(red);
					unifi.SetColor(red);
					poisson.SetColor(red);
					logNormal.SetColor(red);
				}
				
				//If the user has Xed out the window
				if( event.type == SDL_QUIT )
					{
					//Quit the program
					_quit = true;
					}
			}

	    //Display all
	    ok.Show(_screen);
		exp.Show(_screen);
		unifr.Show(_screen);
		unifi.Show(_screen);
		poisson.Show(_screen);
		logNormal.Show(_screen);
	
		meanT.DisplayLeft(_screen,mean, _font2,_textColor);
		
		
		//For some button we just need the mean to set the distribution so in this case we hide the variance
		if((exp.IsActive()==false)&&(poisson.IsActive()==false))
			{
			 varianceT.DisplayRight(_screen,variance, _font2,_textColor);	
			 
			}
		else
			{
			 ApplySurface(400,398,hide,_screen.GetScreen());
			}

		_screen.Display();
	}
	
	_screen.Clean("Images/background.png");

	//Then we save the parameters in the Gui's attributes

	//First we get the type of arm:
	if(exp.IsActive()){armType='A';}
	if(unifr.IsActive()){armType='B';}
	if(unifi.IsActive()){armType='C';}
	if(poisson.IsActive()){armType='D';}
	if(logNormal.IsActive()){armType='E';}

	std::vector<double> parameter;
	
	//Then acoording to the type of arms we calculate the parameters required
	switch(armType)
		{
		case 'A'://Exponential: we need the lambda

			_choices.push_back('A');//we save the type in _choices 

			
			parameter.push_back(1.0/(mean*1.0));
			_parameters.push_back(parameter);//and the parameters calculated using the mean and the variance in _parameters

			break;
		case 'B'://uniform real on [a,b]  we need a and b

			_choices.push_back('B');

			
			parameter.push_back((2.0*mean-sqrt(12.0*variance))/2.0);
			parameter.push_back((2.0*mean+sqrt(12.0*variance))/2.0);
			_parameters.push_back(parameter);
			break;


		case 'C':

			_choices.push_back('C');//uniform integer on [a,b] we need a and b

			
			parameter.push_back((2.0*mean -sqrt(12.0*variance+1.0)+1)/2.0);
			parameter.push_back((2.0*mean+sqrt(12.0*variance+1)-1)/2.0);
			_parameters.push_back(parameter);
			break;


		case 'D': //poisson we just need the mu wich equal to the mean

			_choices.push_back('D');

			
			parameter.push_back(mean);
			_parameters.push_back(parameter);
			break;

		default:

			_choices.push_back('E'); //log-normal we need mu and sigma square

			
			parameter.push_back(log(mean*1.0)-0.5*log(1.0+((variance*1.0)/(mean*mean*1.0))));
			parameter.push_back((2.0*mean+sqrt(12.0*variance+1.0)-1.0)/2.0);
			_parameters.push_back(parameter);
			break;		

		}


}