/***********************************************************************//** * @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; }
/***********************************************************************//** * @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; }
/***********************************************************************//** * @brief Bin the event data * * This method loops over all observations found in the observation conatiner * and bins all events from the event list(s) into counts map(s). Note that * each event list is binned in a separate counts map, hence no summing of * events is done. ***************************************************************************/ void ctbin::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(); // Write parameters into logger if (logTerse()) { log_parameters(); log << 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("Bin observations"); } else { log.header1("Bin observation"); } } // Loop over all observations in the container 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) { log.header3("Observation "+obs->name()); } else { log.header3("Observation"); } } // Fill the cube fill_cube(obs); // Dispose events to free memory obs->dispose_events(); } // endif: CTA observation found } // endfor: looped over observations // Set a single cube in the observation container obs_cube(); // Write observation(s) into logger if (logTerse()) { log << std::endl; if (m_obs.size() > 1) { log.header1("Binned observations"); } else { log.header1("Binned observation"); } log << m_obs << std::endl; } // Return return; }
/***********************************************************************//** * @brief Generate the model map(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 a model map for each CTA observation. ***************************************************************************/ void ctmodel::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(); // Setup observation container setup_obs(); // Write parameters into logger if (logTerse()) { log_parameters(); log << 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("Generate model maps"); } else { log.header1("Generate model map"); } } // Initialise observation counter int n_observations = 0; // Loop over all observations in the container for (int i = 0; i < m_obs.size(); ++i) { // Initialise event input and output filenames m_infiles.push_back(""); // 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) { log.header3("Observation "+obs->name()); } else { log.header3("Observation"); } } // Increment number of observations n_observations++; // Save event file name (for possible saving) m_infiles[i] = obs->eventfile(); // Generate model map model_map(obs, m_obs.models()); } // endif: CTA observation found } // endfor: looped over 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 observation(s) into logger if (logTerse()) { log << std::endl; if (m_obs.size() > 1) { log.header1("Observations after model map generation"); } else { log.header1("Observation after model map generation"); } log << m_obs << std::endl; } // Return return; }
/***********************************************************************//** * @brief Select event data * * This method reads in the application parameters and loops over all * observations that were found to perform an event selection. Event * selection is done by writing each observation to a temporary file and * re-opening the temporary file using the cfitsio event filter syntax. * The temporary file is deleted after this action so that no disk overflow * will occur. ***************************************************************************/ void ctselect::run(void) { // Switch screen logging on in debug mode if (logDebug()) { log.cout(true); } // Get parameters get_parameters(); // Write parameters into logger if (logTerse()) { log_parameters(); log << std::endl; } // Write observation(s) into logger if (logTerse()) { log << std::endl; log.header1("Observations before selection"); log << m_obs << std::endl; } // Write header if (logTerse()) { log << std::endl; log.header1("Event selection"); } // Initialise counters int n_observations = 0; // Loop over all observation in the container for (int i = 0; i < m_obs.size(); ++i) { // Initialise event input and output filenames m_infiles.push_back(""); // 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) { log.header3("Observation "+obs->name()); } else { log.header3("Observation"); } } // Increment counter n_observations++; // Save event file name (for possible saving) m_infiles[i] = obs->eventfile(); // Get temporary file name std::string filename = std::tmpnam(NULL); // Save observation in temporary file obs->save(filename, true); // Log saved FITS file if (logExplicit()) { GFits tmpfile(filename); log << std::endl; log.header1("FITS file content of temporary file"); log << tmpfile << std::endl; tmpfile.close(); } // Check temporary file std::string message = check_infile(filename); if (message.length() > 0) { throw GException::app_error(G_RUN, message); } // Load observation from temporary file, including event selection select_events(obs, filename); // Remove temporary file std::remove(filename.c_str()); } // endif: had a CTA observation } // endfor: looped over all 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 observation(s) into logger if (logTerse()) { log << std::endl; log.header1("Observations after selection"); log << m_obs << std::endl; } // Return return; }