Commit fbfd864add43a1c9747cf475c7066e57d985b95f

Authored by Jürgen Knödlseder
1 parent 93799538

Implement "DATE" method in GSPIModelDataSpace (#745)

inst/spi/include/GSPIModelDataSpace.hpp
... ... @@ -89,45 +89,47 @@ public:
89 89  
90 90 protected:
91 91 // Protected methods
92   - void init_members(void);
93   - void copy_members(const GSPIModelDataSpace& model);
94   - void free_members(void);
95   - void set_pointers(void);
96   - void setup_model(const GObservation& obs) const;
97   - void setup_pars(GSPIEventCube* cube);
98   - void setup_pointing_indices(GSPIEventCube* cube,
  92 + void init_members(void);
  93 + void copy_members(const GSPIModelDataSpace& model);
  94 + void free_members(void);
  95 + void set_pointers(void);
  96 + void setup_model(const GObservation& obs) const;
  97 + void setup_pars(GSPIEventCube* cube);
  98 + void setup_pointing_indices(GSPIEventCube* cube,
  99 + std::vector<int>* indices,
  100 + std::vector<std::string>* names);
  101 + void setup_detector_indices(GSPIEventCube* cube,
  102 + std::vector<int>* indices,
  103 + std::vector<std::string>* names);
  104 + void setup_energy_indices(GSPIEventCube* cube,
99 105 std::vector<int>* indices,
100 106 std::vector<std::string>* names);
101   - void setup_detector_indices(GSPIEventCube* cube,
102   - std::vector<int>* indices,
103   - std::vector<std::string>* names);
104   - void setup_energy_indices(GSPIEventCube* cube,
105   - std::vector<int>* indices,
106   - std::vector<std::string>* names);
107   - void setup_point(GSPIEventCube* cube,
108   - std::vector<int>* indices,
109   - std::vector<std::string>* names);
110   - void setup_orbit(GSPIEventCube* cube,
111   - std::vector<int>* indices,
112   - std::vector<std::string>* names);
113   - void setup_date(GSPIEventCube* cube,
114   - std::vector<int>* indices,
115   - std::vector<std::string>* names);
116   - void add_gedfail(GSPIEventCube* cube,
117   - std::vector<int>* indices,
118   - std::vector<std::string>* names);
119   - void add_gedanneal(GSPIEventCube* cube,
  107 + void setup_point(GSPIEventCube* cube,
  108 + std::vector<int>* indices,
  109 + std::vector<std::string>* names);
  110 + void setup_orbit(GSPIEventCube* cube,
  111 + std::vector<int>* indices,
  112 + std::vector<std::string>* names);
  113 + void setup_date(GSPIEventCube* cube,
  114 + std::vector<int>* indices,
  115 + std::vector<std::string>* names,
  116 + const double& time);
  117 + void add_gedfail(GSPIEventCube* cube,
120 118 std::vector<int>* indices,
121 119 std::vector<std::string>* names);
122   - void setup_dete(GSPIEventCube* cube,
123   - std::vector<int>* indices,
124   - std::vector<std::string>* names);
125   - void setup_evtclass(GSPIEventCube* cube,
126   - std::vector<int>* indices,
127   - std::vector<std::string>* names);
128   - void setup_ebin(GSPIEventCube* cube,
129   - std::vector<int>* indices,
130   - std::vector<std::string>* names);
  120 + void add_gedanneal(GSPIEventCube* cube,
  121 + std::vector<int>* indices,
  122 + std::vector<std::string>* names);
  123 + void setup_dete(GSPIEventCube* cube,
  124 + std::vector<int>* indices,
  125 + std::vector<std::string>* names);
  126 + void setup_evtclass(GSPIEventCube* cube,
  127 + std::vector<int>* indices,
  128 + std::vector<std::string>* names);
  129 + void setup_ebin(GSPIEventCube* cube,
  130 + std::vector<int>* indices,
  131 + std::vector<std::string>* names);
  132 + double get_date_time(const std::string& method) const;
131 133  
132 134 // Protected data members
133 135 mutable GSPIObservation* m_obs; //!< SPI observation
... ...
inst/spi/src/GSPIModelDataSpace.cpp
... ... @@ -50,6 +50,7 @@ const GModelRegistry g_spi_data_space_registry(&amp;g_spi_data_space_seed);
50 50 #define G_READ "GSPIModelDataSpace::read(GXmlElement&)"
51 51 #define G_WRITE "GSPIModelDataSpace::write(GXmlElement&)"
52 52 #define G_SETUP_MODEL "GSPIModelDataSpace::setup_model(Observation&)"
  53 +#define G_GET_DATE_TIME "GSPIModelDataSpace::get_date_time(std::string&)"
53 54  
54 55 /* __ Macros _____________________________________________________________ */
55 56  
... ... @@ -1017,7 +1018,8 @@ void GSPIModelDataSpace::setup_pointing_indices(GSPIEventCube* cube,
1017 1018  
1018 1019 // Search for "date"
1019 1020 else if (gammalib::contains(method, "date")) {
1020   - setup_date(cube, indices, names);
  1021 + double time = get_date_time(method);
  1022 + setup_date(cube, indices, names, time);
1021 1023 }
1022 1024  
1023 1025 // Handle "gedfail"
... ... @@ -1181,14 +1183,73 @@ void GSPIModelDataSpace::setup_orbit(GSPIEventCube* cube,
1181 1183 * @param[in] cube Event cube.
1182 1184 * @param[in,out] indices Vector of pointing indices.
1183 1185 * @param[in,out] names Vector of pointing names.
  1186 + * @param[in] time Time scale in seconds.
1184 1187 *
1185 1188 * Setup vectors of pointing indices and names for "date" method.
1186 1189 ***************************************************************************/
1187 1190 void GSPIModelDataSpace::setup_date(GSPIEventCube* cube,
1188 1191 std::vector<int>* indices,
1189   - std::vector<std::string>* names)
  1192 + std::vector<std::string>* names,
  1193 + const double& time)
1190 1194 {
1191   - // TODO: implement "date" method
  1195 + // Compute start time, number of time bins and length of time bin in
  1196 + // seconds
  1197 + double tstart = cube->gti().tstart().secs();
  1198 + double tbin = cube->gti().telapse();
  1199 + int nbins = int(tbin / time + 0.5);
  1200 + if (nbins < 1) {
  1201 + nbins = 1;
  1202 + }
  1203 + tbin /= double(nbins);
  1204 +
  1205 + // Get number of pointings
  1206 + int npt = indices->size();
  1207 +
  1208 + // Loop over all pointings
  1209 + for (int ipt = 0; ipt < npt; ++ipt) {
  1210 +
  1211 + // Get time of pointing in seconds
  1212 + double t = 0.5 * (cube->gti().tstart(ipt).secs() +
  1213 + cube->gti().tstop(ipt).secs());
  1214 +
  1215 + // Compute grouping index. Make sure that it is in valid range.
  1216 + int index = int((t - tstart) / tbin);
  1217 + if (index < 0) {
  1218 + index = 0;
  1219 + }
  1220 + else if (index >= nbins) {
  1221 + index = nbins - 1;
  1222 + }
  1223 +
  1224 + // Store index
  1225 + (*indices)[ipt] = index;
  1226 +
  1227 + } // endfor: looped over indices
  1228 +
  1229 + // Remove unused indices
  1230 + for (int index = 0, used_index = 0; index < nbins; ++index) {
  1231 +
  1232 + // Replace all indices "index" by "used_index"
  1233 + int nindex = 0;
  1234 + for (int ipt = 0; ipt < npt; ++ipt) {
  1235 + if ((*indices)[ipt] == index) {
  1236 + (*indices)[ipt] = used_index;
  1237 + nindex++;
  1238 + }
  1239 + }
  1240 +
  1241 + // If we found indices to replaced the increase "used_index"
  1242 + if (nindex > 0) {
  1243 +
  1244 + // Add date to names
  1245 + names->push_back("T" + gammalib::str(used_index, "%6.6d"));
  1246 +
  1247 + // Increment used index
  1248 + used_index++;
  1249 +
  1250 + } // endif: index was used
  1251 +
  1252 + } // endfor: looped over all pointings
1192 1253  
1193 1254 // Return
1194 1255 return;
... ... @@ -1309,3 +1370,56 @@ void GSPIModelDataSpace::setup_ebin(GSPIEventCube* cube,
1309 1370 // Return
1310 1371 return;
1311 1372 }
  1373 +
  1374 +
  1375 +/***********************************************************************//**
  1376 + * @brief Get time scale from method string
  1377 + *
  1378 + * @param[in] method Method string.
  1379 + * @return Time scale (seconds).
  1380 + *
  1381 + * Get the time scale for the "DATE" method from the method string. The
  1382 + * following time units are supported: min, hour, day, week, month or year.
  1383 + ***************************************************************************/
  1384 +double GSPIModelDataSpace::get_date_time(const std::string& method) const
  1385 +{
  1386 + // Get position of "date" method in string
  1387 + size_t start = method.find("date") + 4;
  1388 +
  1389 + // Get scale of time
  1390 + double scale = 0.0;
  1391 + size_t stop = std::string::npos;
  1392 + if ((stop = method.find("min", start)) != std::string::npos) {
  1393 + scale = 60.0;
  1394 + }
  1395 + else if ((stop = method.find("hour", start)) != std::string::npos) {
  1396 + scale = 3600.0;
  1397 + }
  1398 + else if ((stop = method.find("day", start)) != std::string::npos) {
  1399 + scale = 86400.0;
  1400 + }
  1401 + else if ((stop = method.find("week", start)) != std::string::npos) {
  1402 + scale = 604800.0;
  1403 + }
  1404 + else if ((stop = method.find("month", start)) != std::string::npos) {
  1405 + scale = 2628000.0;
  1406 + }
  1407 + else if ((stop = method.find("year", start)) != std::string::npos) {
  1408 + scale = 31536000.0;
  1409 + }
  1410 +
  1411 + // Throw an exception if no time scale was found
  1412 + if (stop == std::string::npos) {
  1413 + std::string msg = "Method string \""+method+"\" does not contain "
  1414 + "time units for \"DATE\" method. Please specify one "
  1415 + "of the following units: min, hour, day, week, "
  1416 + "month or year.";
  1417 + throw GException::invalid_value(G_GET_DATE_TIME, msg);
  1418 + }
  1419 +
  1420 + // Get time in seconds
  1421 + double time = gammalib::todouble(method.substr(start, stop-start)) * scale;
  1422 +
  1423 + // Return time
  1424 + return time;
  1425 +}
... ...
inst/spi/test/test_SPI.cpp
... ... @@ -271,6 +271,26 @@ void TestGSPI::test_modeldataspace(void)
271 271 test_value(model6.size(), 88, "POINT instance size");
272 272 test_value(model6[35].name(), "GEDSAT P000035", "POINT instance parameter");
273 273  
  274 + // Construct "date 10 min" model from OG
  275 + GSPIModelDataSpace model7(obs, "GEDSAT", "date 10 mins", 0);
  276 + test_value(model7.size(), 88, "DATE 10 MIN instance size");
  277 + test_value(model7[35].name(), "GEDSAT T000035", "DATE 10 MIN instance parameter");
  278 +
  279 + // Construct "date 3 hours" model from OG
  280 + GSPIModelDataSpace model8(obs, "GEDSAT", "date 3 hours", 0);
  281 + test_value(model8.size(), 20, "DATE 3 HOURS instance size");
  282 + test_value(model8[5].name(), "GEDSAT T000005", "DATE 3 HOURS instance parameter");
  283 +
  284 + // Construct "date 1 day" model from OG
  285 + GSPIModelDataSpace model9(obs, "GEDSAT", "date 1 day", 0);
  286 + test_value(model9.size(), 3, "DATE 1 DAY instance size");
  287 + test_value(model9[1].name(), "GEDSAT T000001", "DATE 1 DAY instance parameter");
  288 +
  289 + // Construct "date 2 weeks" model from OG
  290 + GSPIModelDataSpace model10(obs, "GEDSAT", "date 2 weeks", 0);
  291 + test_value(model10.size(), 1, "DATE 2 WEEKS instance size");
  292 + test_value(model10[0].name(), "GEDSAT T000000", "DATE 2 WEEKS instance parameter");
  293 +
274 294 // Return
275 295 return;
276 296 }
... ...