Commit 64e71e40f4c82d94c3671198249f47fb204e4d40
Merge branch '00-07-02' into integration
Conflicts: ChangeLog NEWS scripts/cspull.py
Showing
8 changed files
with
1596 additions
and
1517 deletions
ChangeLog
| ... | ... | @@ -6,6 +6,14 @@ |
| 6 | 6 | Support energy dispersion in ctobssim, ctlike and ctmodel |
| 7 | 7 | |
| 8 | 8 | |
| 9 | +2014-02-10 Juergen Knoedlseder <jurgen.knodlseder@irap.omp.eu> | |
| 10 | + | |
| 11 | + * Bug fix Version 0.7.2 released | |
| 12 | + ================================ | |
| 13 | + | |
| 14 | + Add logL and event statistics to cspull output file | |
| 15 | + | |
| 16 | + | |
| 9 | 17 | 2014-02-05 Juergen Knoedlseder <jurgen.knodlseder@irap.omp.eu> |
| 10 | 18 | |
| 11 | 19 | * Bug fix Version 0.7.1 released | ... | ... |
NEWS
| ... | ... | @@ -2,7 +2,7 @@ New Features and Important Changes in ctools 00-08-00 |
| 2 | 2 | |
| 3 | 3 | Author(s) : Juergen Knoedlseder |
| 4 | 4 | |
| 5 | -5 February 2014 | |
| 5 | +10 February 2014 | |
| 6 | 6 | |
| 7 | 7 | |
| 8 | 8 | 1. Introduction |
| ... | ... | @@ -13,13 +13,7 @@ important changes made since the last release of ctools. |
| 13 | 13 | |
| 14 | 14 | 2. Configuration |
| 15 | 15 | ----------------- |
| 16 | -Some hyphens were missing in the configuration script when synchronising | |
| 17 | -the user and system parameter files. This led to an error message on the | |
| 18 | -console, but did not impact the proper configuration. Hyphens have now | |
| 19 | -been added as needed. | |
| 20 | - | |
| 21 | -The configuration test script testconf.sh has been added to allow testing | |
| 22 | -configuration script during continous integration. | |
| 16 | +None | |
| 23 | 17 | |
| 24 | 18 | |
| 25 | 19 | 3. Python interface |
| ... | ... | @@ -29,13 +23,7 @@ None |
| 29 | 23 | |
| 30 | 24 | 4. ctobssim - CTA observation simulation |
| 31 | 25 | ---------------------------------------- |
| 32 | -The instrument and id attributes provided by an observation were not | |
| 33 | -considering when simulating source and background events. This has been | |
| 34 | -changed now that only events will be simulated when the instrument | |
| 35 | -and id are valid for a given model. | |
| 36 | - | |
| 37 | -ctobssim now has full access to the calibration database, allowing | |
| 38 | -the use for 2D response functions in FITS files. | |
| 26 | +None | |
| 39 | 27 | |
| 40 | 28 | ctobssim now also supports the handling of energy dispersion. Energy |
| 41 | 29 | dispersion can be switched on or off using the hidden edisp parameter. |
| ... | ... | @@ -81,8 +69,9 @@ None |
| 81 | 69 | |
| 82 | 70 | 11. Scripts |
| 83 | 71 | ----------- |
| 84 | -The obsutils.py script has been adapted to the new calibration database | |
| 85 | -interface. | |
| 72 | +Add logL and event statistics to cspull output file. | |
| 73 | + | |
| 74 | +Convert all tabs into spaces. | |
| 86 | 75 | |
| 87 | 76 | |
| 88 | 77 | 12. caldb | ... | ... |
scripts/cspull.py
| ... | ... | @@ -30,54 +30,55 @@ import math |
| 30 | 30 | # cspull class # |
| 31 | 31 | # ============ # |
| 32 | 32 | class cspull(GApplication): |
| 33 | - """ | |
| 34 | - This class implements the pull distribution generation script. It derives | |
| 35 | - from the GammaLib::GApplication class which provides support for parameter | |
| 36 | - files, command line arguments, and logging. In that way the Python | |
| 37 | - script behaves just as a regular ctool. | |
| 38 | - """ | |
| 39 | - def __init__(self, *argv): | |
| 40 | - """ | |
| 41 | - Constructor. | |
| 42 | - """ | |
| 43 | - # Set name | |
| 44 | - self.name = "cspull" | |
| 45 | - self.version = "0.2.0" | |
| 46 | - | |
| 47 | - # Initialise some members | |
| 48 | - self.obs = None | |
| 49 | - self.model = None | |
| 50 | - self.m_srcmdl = None | |
| 51 | - | |
| 52 | - # Make sure that parfile exists | |
| 53 | - file = self.parfile() | |
| 33 | + """ | |
| 34 | + This class implements the pull distribution generation script. It derives | |
| 35 | + from the GammaLib::GApplication class which provides support for parameter | |
| 36 | + files, command line arguments, and logging. In that way the Python | |
| 37 | + script behaves just as a regular ctool. | |
| 38 | + """ | |
| 39 | + def __init__(self, *argv): | |
| 40 | + """ | |
| 41 | + Constructor. | |
| 42 | + """ | |
| 43 | + # Set name | |
| 44 | + self.name = "cspull" | |
| 45 | + self.version = "0.2.0" | |
| 46 | + | |
| 47 | + # Initialise some members | |
| 48 | + self.obs = None | |
| 49 | + self.model = None | |
| 50 | + self.m_srcmdl = None | |
| 51 | + | |
| 52 | + # Make sure that parfile exists | |
| 53 | + file = self.parfile() | |
| 54 | 54 | |
| 55 | - # Initialise application | |
| 56 | - if len(argv) == 0: | |
| 57 | - GApplication.__init__(self, self.name, self.version) | |
| 58 | - elif len(argv) ==1: | |
| 59 | - GApplication.__init__(self, self.name, self.version, *argv) | |
| 60 | - else: | |
| 61 | - raise TypeError("Invalid number of arguments given.") | |
| 55 | + # Initialise application | |
| 56 | + if len(argv) == 0: | |
| 57 | + GApplication.__init__(self, self.name, self.version) | |
| 58 | + elif len(argv) ==1: | |
| 59 | + GApplication.__init__(self, self.name, self.version, *argv) | |
| 60 | + else: | |
| 61 | + raise TypeError("Invalid number of arguments given.") | |
| 62 | 62 | |
| 63 | - # Set logger properties | |
| 64 | - self.log_header() | |
| 65 | - self.log.date(True) | |
| 63 | + # Set logger properties | |
| 64 | + self.log_header() | |
| 65 | + self.log.date(True) | |
| 66 | 66 | |
| 67 | - # Return | |
| 68 | - return | |
| 69 | - | |
| 70 | - def __del__(self): | |
| 71 | - """ | |
| 72 | - Destructor. | |
| 73 | - """ | |
| 74 | - # Write separator into logger | |
| 75 | - if self.logTerse(): | |
| 76 | - self.log("\n") | |
| 77 | - | |
| 78 | - # Return | |
| 79 | - return | |
| 67 | + # Return | |
| 68 | + return | |
| 69 | + | |
| 70 | + def __del__(self): | |
| 71 | + """ | |
| 72 | + Destructor. | |
| 73 | + """ | |
| 74 | + # Write separator into logger | |
| 75 | + if self.logTerse(): | |
| 76 | + self.log("\n") | |
| 77 | + | |
| 78 | + # Return | |
| 79 | + return | |
| 80 | 80 | |
| 81 | +<<<<<<< HEAD | |
| 81 | 82 | def parfile(self): |
| 82 | 83 | """ |
| 83 | 84 | Check if parfile exists. If parfile does not exist then create a |
| ... | ... | @@ -138,132 +139,193 @@ class cspull(GApplication): |
| 138 | 139 | self.m_rad = self["rad"].real() |
| 139 | 140 | self.m_npix = self["npix"].integer() |
| 140 | 141 | self.m_binsz = self["binsz"].real() |
| 142 | +======= | |
| 143 | + def parfile(self): | |
| 144 | + """ | |
| 145 | + Check if parfile exists. If parfile does not exist then create a | |
| 146 | + default parfile. This kluge avoids shipping the cscript with a parfile. | |
| 147 | + """ | |
| 148 | + # Set parfile name | |
| 149 | + parfile = self.name+".par" | |
| 150 | + | |
| 151 | + try: | |
| 152 | + pars = GApplicationPars(parfile) | |
| 153 | + except: | |
| 154 | + # Signal if parfile was not found | |
| 155 | + sys.stdout.write("Parfile "+parfile+" not found. Create default parfile.\n") | |
| 156 | + | |
| 157 | + # Create default parfile | |
| 158 | + pars = GApplicationPars() | |
| 159 | + pars.append(GApplicationPar("srcmdl","f","a","$GAMMALIB/share/models/crab.xml","","","Source model")) | |
| 160 | + pars.append(GApplicationPar("outfile","f","a","pull.dat","","","Output file name")) | |
| 161 | + pars.append(GApplicationPar("ntrials","i","a","10","","","Number of trials")) | |
| 162 | + pars.append(GApplicationPar("caldb","s","h","","","","Calibration database")) | |
| 163 | + pars.append(GApplicationPar("irf","s","a","cta_dummy_irf","","","Instrument response function")) | |
| 164 | + pars.append(GApplicationPar("ra","r","a","83.6331","0","360","RA of pointing (deg)")) | |
| 165 | + pars.append(GApplicationPar("dec","r","a","22.0145","-90","90","Dec of pointing (deg)")) | |
| 166 | + pars.append(GApplicationPar("emin","r","a","0.1","0.0","","Lower energy limit (TeV)")) | |
| 167 | + pars.append(GApplicationPar("emax","r","a","100.0","0.0","","Upper energy limit (TeV)")) | |
| 168 | + pars.append(GApplicationPar("enumbins","i","a","0","","","Number of energy bins (0=unbinned)")) | |
| 169 | + pars.append(GApplicationPar("duration","r","a","180000.0","","","Effective exposure time (s)")) | |
| 170 | + pars.append(GApplicationPar("deadc","r","h","0.95","","","Deadtime correction factor")) | |
| 171 | + pars.append(GApplicationPar("rad","r","h","5.0","","","Radius of ROI (deg)")) | |
| 172 | + pars.append(GApplicationPar("npix","i","h","200","","","Number of pixels for binned")) | |
| 173 | + pars.append(GApplicationPar("binsz","r","h","0.05","","","Pixel size for binned (deg/pixel)")) | |
| 174 | + pars.append_standard() | |
| 175 | + pars.save(parfile) | |
| 176 | + | |
| 177 | + # Return | |
| 178 | + return | |
| 179 | + | |
| 180 | + def get_parameters(self): | |
| 181 | + """ | |
| 182 | + Get parameters from parfile and setup the observation. | |
| 183 | + """ | |
| 184 | + # Get parameters | |
| 185 | + if self.model == None: | |
| 186 | + self.m_srcmdl = self["srcmdl"].filename() | |
| 187 | + self.m_outfile = self["outfile"].filename() | |
| 188 | + self.m_ntrials = self["ntrials"].integer() | |
| 189 | + self.m_caldb = self["caldb"].string() | |
| 190 | + self.m_irf = self["irf"].string() | |
| 191 | + self.m_ra = self["ra"].real() | |
| 192 | + self.m_dec = self["dec"].real() | |
| 193 | + self.m_emin = self["emin"].real() | |
| 194 | + self.m_emax = self["emax"].real() | |
| 195 | + self.m_enumbins = self["enumbins"].integer() | |
| 196 | + self.m_duration = self["duration"].real() | |
| 197 | + self.m_deadc = self["deadc"].real() | |
| 198 | + self.m_rad = self["rad"].real() | |
| 199 | + self.m_npix = self["npix"].integer() | |
| 200 | + self.m_binsz = self["binsz"].real() | |
| 201 | +>>>>>>> 00-07-02 | |
| 141 | 202 | |
| 142 | - # Set some fixed parameters | |
| 143 | - self.m_log = False # Logging in client tools | |
| 144 | - self.m_debug = False # Debugging in client tools | |
| 145 | - | |
| 146 | - # Setup observation | |
| 147 | - self.obs = self.set_obs(ra=self.m_ra, dec=self.m_dec, \ | |
| 148 | - emin=self.m_emin, emax=self.m_emax) | |
| 149 | - | |
| 150 | - # Load source model | |
| 151 | - if self.m_srcmdl != None: | |
| 152 | - self.model = GModels(self.m_srcmdl) | |
| 153 | - | |
| 154 | - # Append source model to observation | |
| 155 | - self.obs.models(self.model) | |
| 203 | + # Set some fixed parameters | |
| 204 | + self.m_log = False # Logging in client tools | |
| 205 | + self.m_debug = False # Debugging in client tools | |
| 206 | + | |
| 207 | + # Setup observation | |
| 208 | + self.obs = self.set_obs(ra=self.m_ra, dec=self.m_dec, \ | |
| 209 | + emin=self.m_emin, emax=self.m_emax) | |
| 210 | + | |
| 211 | + # Load source model | |
| 212 | + if self.m_srcmdl != None: | |
| 213 | + self.model = GModels(self.m_srcmdl) | |
| 214 | + | |
| 215 | + # Append source model to observation | |
| 216 | + self.obs.models(self.model) | |
| 156 | 217 | |
| 157 | - # Return | |
| 158 | - return | |
| 159 | - | |
| 160 | - def models(self, models): | |
| 161 | - """ | |
| 162 | - Set model. | |
| 163 | - """ | |
| 164 | - # Copy models | |
| 165 | - self.model = models.copy() | |
| 166 | - | |
| 167 | - # Return | |
| 168 | - return | |
| 169 | - | |
| 170 | - def execute(self): | |
| 171 | - """ | |
| 172 | - Execute the script. | |
| 173 | - """ | |
| 174 | - # Run the script | |
| 175 | - self.run() | |
| 176 | - | |
| 177 | - # Return | |
| 178 | - return | |
| 218 | + # Return | |
| 219 | + return | |
| 220 | + | |
| 221 | + def models(self, models): | |
| 222 | + """ | |
| 223 | + Set model. | |
| 224 | + """ | |
| 225 | + # Copy models | |
| 226 | + self.model = models.copy() | |
| 227 | + | |
| 228 | + # Return | |
| 229 | + return | |
| 230 | + | |
| 231 | + def execute(self): | |
| 232 | + """ | |
| 233 | + Execute the script. | |
| 234 | + """ | |
| 235 | + # Run the script | |
| 236 | + self.run() | |
| 237 | + | |
| 238 | + # Return | |
| 239 | + return | |
| 179 | 240 | |
| 180 | - def run(self): | |
| 181 | - """ | |
| 182 | - Run the script. | |
| 183 | - """ | |
| 184 | - # Switch screen logging on in debug mode | |
| 185 | - if self.logDebug(): | |
| 186 | - self.log.cout(True) | |
| 241 | + def run(self): | |
| 242 | + """ | |
| 243 | + Run the script. | |
| 244 | + """ | |
| 245 | + # Switch screen logging on in debug mode | |
| 246 | + if self.logDebug(): | |
| 247 | + self.log.cout(True) | |
| 187 | 248 | |
| 188 | - # Get parameters | |
| 189 | - self.get_parameters() | |
| 190 | - | |
| 191 | - # Write input parameters into logger | |
| 192 | - if self.logTerse(): | |
| 193 | - self.log_parameters() | |
| 194 | - self.log("\n") | |
| 195 | - | |
| 196 | - # Write observation into logger | |
| 197 | - if self.logTerse(): | |
| 198 | - self.log("\n") | |
| 199 | - self.log.header1("Observation") | |
| 200 | - self.log(str(self.obs)) | |
| 201 | - self.log("\n") | |
| 249 | + # Get parameters | |
| 250 | + self.get_parameters() | |
| 251 | + | |
| 252 | + # Write input parameters into logger | |
| 253 | + if self.logTerse(): | |
| 254 | + self.log_parameters() | |
| 255 | + self.log("\n") | |
| 256 | + | |
| 257 | + # Write observation into logger | |
| 258 | + if self.logTerse(): | |
| 259 | + self.log("\n") | |
| 260 | + self.log.header1("Observation") | |
| 261 | + self.log(str(self.obs)) | |
| 262 | + self.log("\n") | |
| 202 | 263 | |
| 203 | - # Write header | |
| 204 | - if self.logTerse(): | |
| 205 | - self.log("\n") | |
| 206 | - self.log.header1("Generate pull distribution") | |
| 264 | + # Write header | |
| 265 | + if self.logTerse(): | |
| 266 | + self.log("\n") | |
| 267 | + self.log.header1("Generate pull distribution") | |
| 207 | 268 | |
| 208 | - # Loop over trials | |
| 209 | - for seed in range(self.m_ntrials): | |
| 210 | - | |
| 211 | - # Make a trial | |
| 212 | - result = self.trial(seed) | |
| 213 | - | |
| 214 | - # Write out result immediately | |
| 215 | - if seed == 0: | |
| 216 | - file = open(self.m_outfile, 'w') | |
| 217 | - writer = csv.DictWriter(file, result['colnames']) | |
| 218 | - writer.writerow(dict((_,_) for _ in result['colnames'])) | |
| 219 | - else: | |
| 220 | - file = open(self.m_outfile, 'a') | |
| 221 | - writer = csv.DictWriter(file, result['colnames']) | |
| 222 | - writer.writerow(result['values']) | |
| 223 | - file.close() | |
| 224 | - | |
| 225 | - # Return | |
| 226 | - return | |
| 227 | - | |
| 228 | - def set_obs(self, ra=83.6331, dec=22.0145, emin=0.1, emax=100.0): | |
| 229 | - """ | |
| 230 | - Returns an observation container with a single CTA observation. | |
| 231 | - | |
| 232 | - Keywords: | |
| 233 | - ra - Right Ascension of pointing [deg] (default: 83.6331) | |
| 234 | - dec - Declination of pointing [deg] (default: 22.0145) | |
| 235 | - emin - Minimum energy [TeV] (default: 0.1) | |
| 236 | - emax - Maximum energy [TeV] (default: 100.0) | |
| 237 | - """ | |
| 238 | - # Allocate observation container | |
| 239 | - obs = GObservations() | |
| 240 | - | |
| 241 | - # Set single pointing | |
| 242 | - pntdir = GSkyDir() | |
| 243 | - pntdir.radec_deg(ra, dec) | |
| 244 | - | |
| 245 | - # Create CTA observation | |
| 246 | - run = obsutils.set(pntdir, caldb=self.m_caldb, irf=self.m_irf, \ | |
| 247 | - duration=self.m_duration, deadc=self.m_deadc, \ | |
| 269 | + # Loop over trials | |
| 270 | + for seed in range(self.m_ntrials): | |
| 271 | + | |
| 272 | + # Make a trial | |
| 273 | + result = self.trial(seed) | |
| 274 | + | |
| 275 | + # Write out result immediately | |
| 276 | + if seed == 0: | |
| 277 | + file = open(self.m_outfile, 'w') | |
| 278 | + writer = csv.DictWriter(file, result['colnames']) | |
| 279 | + writer.writerow(dict((_,_) for _ in result['colnames'])) | |
| 280 | + else: | |
| 281 | + file = open(self.m_outfile, 'a') | |
| 282 | + writer = csv.DictWriter(file, result['colnames']) | |
| 283 | + writer.writerow(result['values']) | |
| 284 | + file.close() | |
| 285 | + | |
| 286 | + # Return | |
| 287 | + return | |
| 288 | + | |
| 289 | + def set_obs(self, ra=83.6331, dec=22.0145, emin=0.1, emax=100.0): | |
| 290 | + """ | |
| 291 | + Returns an observation container with a single CTA observation. | |
| 292 | + | |
| 293 | + Keywords: | |
| 294 | + ra - Right Ascension of pointing [deg] (default: 83.6331) | |
| 295 | + dec - Declination of pointing [deg] (default: 22.0145) | |
| 296 | + emin - Minimum energy [TeV] (default: 0.1) | |
| 297 | + emax - Maximum energy [TeV] (default: 100.0) | |
| 298 | + """ | |
| 299 | + # Allocate observation container | |
| 300 | + obs = GObservations() | |
| 301 | + | |
| 302 | + # Set single pointing | |
| 303 | + pntdir = GSkyDir() | |
| 304 | + pntdir.radec_deg(ra, dec) | |
| 305 | + | |
| 306 | + # Create CTA observation | |
| 307 | + run = obsutils.set(pntdir, caldb=self.m_caldb, irf=self.m_irf, \ | |
| 308 | + duration=self.m_duration, deadc=self.m_deadc, \ | |
| 248 | 309 | emin=emin, emax=emax, rad=self.m_rad) |
| 249 | - | |
| 250 | - # Append observation to container | |
| 251 | - obs.append(run) | |
| 252 | - | |
| 253 | - # Return observation container | |
| 254 | - return obs | |
| 255 | - | |
| 256 | - def trial(self, seed): | |
| 257 | - """ | |
| 258 | - Create the pull for a single trial. | |
| 259 | - | |
| 260 | - Parameters: | |
| 261 | - seed - Random number generator seed | |
| 262 | - """ | |
| 263 | - # Write header | |
| 264 | - if self.logExplicit(): | |
| 265 | - self.log.header2("Trial "+str(seed+1)) | |
| 310 | + | |
| 311 | + # Append observation to container | |
| 312 | + obs.append(run) | |
| 313 | + | |
| 314 | + # Return observation container | |
| 315 | + return obs | |
| 316 | + | |
| 317 | + def trial(self, seed): | |
| 318 | + """ | |
| 319 | + Create the pull for a single trial. | |
| 320 | + | |
| 321 | + Parameters: | |
| 322 | + seed - Random number generator seed | |
| 323 | + """ | |
| 324 | + # Write header | |
| 325 | + if self.logExplicit(): | |
| 326 | + self.log.header2("Trial "+str(seed+1)) | |
| 266 | 327 | |
| 328 | +<<<<<<< HEAD | |
| 267 | 329 | # Simulate events |
| 268 | 330 | obs = obsutils.sim(self.obs, \ |
| 269 | 331 | nbins=self.m_enumbins, \ |
| ... | ... | @@ -272,94 +334,114 @@ class cspull(GApplication): |
| 272 | 334 | npix=self.m_npix, \ |
| 273 | 335 | edisp=self.m_edisp, \ |
| 274 | 336 | log=self.m_log, debug=self.m_debug) |
| 337 | +======= | |
| 338 | + # Simulate events | |
| 339 | + obs = obsutils.sim(self.obs, \ | |
| 340 | + nbins=self.m_enumbins, \ | |
| 341 | + seed=seed, \ | |
| 342 | + binsz=self.m_binsz, \ | |
| 343 | + npix=self.m_npix, \ | |
| 344 | + log=self.m_log, debug=self.m_debug) | |
| 345 | +>>>>>>> 00-07-02 | |
| 275 | 346 | |
| 276 | - # Determine number of events in simulation | |
| 277 | - nevents = 0.0 | |
| 278 | - for run in obs: | |
| 279 | - nevents += run.events().number() | |
| 347 | + # Determine number of events in simulation | |
| 348 | + nevents = 0.0 | |
| 349 | + for run in obs: | |
| 350 | + nevents += run.events().number() | |
| 280 | 351 | |
| 281 | - # Write simulation results | |
| 282 | - if self.logExplicit(): | |
| 283 | - self.log.header3("Simulation") | |
| 284 | - self.log.parformat("Number of simulated events") | |
| 285 | - self.log(nevents) | |
| 286 | - self.log("\n") | |
| 352 | + # Write simulation results | |
| 353 | + if self.logExplicit(): | |
| 354 | + self.log.header3("Simulation") | |
| 355 | + self.log.parformat("Number of simulated events") | |
| 356 | + self.log(nevents) | |
| 357 | + self.log("\n") | |
| 287 | 358 | |
| 359 | +<<<<<<< HEAD | |
| 288 | 360 | # Fit model |
| 289 | 361 | like = obsutils.fit(obs, edisp=self.m_edisp, \ |
| 290 | 362 | log=self.m_log, debug=self.m_debug) |
| 363 | +======= | |
| 364 | + # Fit model | |
| 365 | + like = obsutils.fit(obs, log=self.m_log, debug=self.m_debug) | |
| 366 | +>>>>>>> 00-07-02 | |
| 291 | 367 | |
| 292 | - # Store results | |
| 293 | - logL = like.opt().value() | |
| 294 | - npred = like.obs().npred() | |
| 295 | - models = like.obs().models() | |
| 368 | + # Store results | |
| 369 | + logL = like.opt().value() | |
| 370 | + npred = like.obs().npred() | |
| 371 | + models = like.obs().models() | |
| 296 | 372 | |
| 297 | - # Write result header | |
| 298 | - if self.logExplicit(): | |
| 299 | - self.log.header3("Pulls") | |
| 300 | - | |
| 301 | - # Gather results | |
| 302 | - colnames = [] | |
| 303 | - values = {} | |
| 304 | - for i in range(models.size()): | |
| 305 | - model = models[i] | |
| 306 | - model_name = model.name() | |
| 307 | - for k in range(model.size()): | |
| 308 | - par = model[k] | |
| 309 | - if par.is_free(): | |
| 310 | - | |
| 311 | - # Set parameter name | |
| 312 | - name = model_name+"_"+par.name() | |
| 313 | - | |
| 314 | - # Append parameter, Pull_parameter and Unc_parameter | |
| 315 | - colnames.append(name) | |
| 316 | - colnames.append("Pull_"+name) | |
| 317 | - colnames.append("Unc_"+name) | |
| 318 | - | |
| 319 | - # Compute pull | |
| 320 | - fitted_value = par.value() | |
| 321 | - real_value = self.model[i][k].value() | |
| 322 | - error = par.error() | |
| 323 | - if error != 0.0: | |
| 324 | - pull = (fitted_value - real_value) / error | |
| 325 | - else: | |
| 326 | - pull = 99.0 | |
| 327 | - | |
| 328 | - # Store results | |
| 329 | - values[name] = fitted_value | |
| 330 | - values["Pull_"+name] = pull | |
| 331 | - values["Unc_"+name] = error | |
| 373 | + # Write result header | |
| 374 | + if self.logExplicit(): | |
| 375 | + self.log.header3("Pulls") | |
| 376 | + | |
| 377 | + # Gather results | |
| 378 | + colnames = [] | |
| 379 | + values = {} | |
| 380 | + colnames.append("LogL") | |
| 381 | + colnames.append("Sim_Events") | |
| 382 | + colnames.append("Npred_Events") | |
| 383 | + values["LogL"] = logL | |
| 384 | + values["Sim_Events"] = nevents | |
| 385 | + values["Npred_Events"] = npred | |
| 386 | + for i in range(models.size()): | |
| 387 | + model = models[i] | |
| 388 | + model_name = model.name() | |
| 389 | + for k in range(model.size()): | |
| 390 | + par = model[k] | |
| 391 | + if par.is_free(): | |
| 392 | + | |
| 393 | + # Set parameter name | |
| 394 | + name = model_name+"_"+par.name() | |
| 395 | + | |
| 396 | + # Append parameter, Pull_parameter and Unc_parameter | |
| 397 | + colnames.append(name) | |
| 398 | + colnames.append("Pull_"+name) | |
| 399 | + colnames.append("Unc_"+name) | |
| 400 | + | |
| 401 | + # Compute pull | |
| 402 | + fitted_value = par.value() | |
| 403 | + real_value = self.model[i][k].value() | |
| 404 | + error = par.error() | |
| 405 | + if error != 0.0: | |
| 406 | + pull = (fitted_value - real_value) / error | |
| 407 | + else: | |
| 408 | + pull = 99.0 | |
| 409 | + | |
| 410 | + # Store results | |
| 411 | + values[name] = fitted_value | |
| 412 | + values["Pull_"+name] = pull | |
| 413 | + values["Unc_"+name] = error | |
| 332 | 414 | |
| 333 | - # Write result | |
| 334 | - if self.logExplicit(): | |
| 335 | - self.log.parformat(name) | |
| 336 | - self.log(pull) | |
| 337 | - self.log(" (") | |
| 338 | - self.log(fitted_value) | |
| 339 | - self.log(" +/- ") | |
| 340 | - self.log(error) | |
| 341 | - self.log(")\n") | |
| 342 | - | |
| 343 | - # Bundle together results | |
| 344 | - result = {'colnames': colnames, 'values': values} | |
| 345 | - | |
| 346 | - # Return | |
| 347 | - return result | |
| 415 | + # Write result | |
| 416 | + if self.logExplicit(): | |
| 417 | + self.log.parformat(name) | |
| 418 | + self.log(pull) | |
| 419 | + self.log(" (") | |
| 420 | + self.log(fitted_value) | |
| 421 | + self.log(" +/- ") | |
| 422 | + self.log(error) | |
| 423 | + self.log(")\n") | |
| 424 | + | |
| 425 | + # Bundle together results | |
| 426 | + result = {'colnames': colnames, 'values': values} | |
| 427 | + | |
| 428 | + # Return | |
| 429 | + return result | |
| 348 | 430 | |
| 349 | 431 | |
| 350 | 432 | # ======================== # |
| 351 | 433 | # Main routine entry point # |
| 352 | 434 | # ======================== # |
| 353 | 435 | if __name__ == '__main__': |
| 354 | - """ | |
| 355 | - Generates pull distribution for a source model. | |
| 356 | - """ | |
| 357 | - # Create instance of application | |
| 358 | - app = cspull(sys.argv) | |
| 359 | - | |
| 360 | - # Open logfile | |
| 361 | - app.logFileOpen() | |
| 362 | - | |
| 363 | - # Execute application | |
| 364 | - app.execute() | |
| 365 | - | |
| 366 | 436 | \ No newline at end of file |
| 437 | + """ | |
| 438 | + Generates pull distribution for a source model. | |
| 439 | + """ | |
| 440 | + # Create instance of application | |
| 441 | + app = cspull(sys.argv) | |
| 442 | + | |
| 443 | + # Open logfile | |
| 444 | + app.logFileOpen() | |
| 445 | + | |
| 446 | + # Execute application | |
| 447 | + app.execute() | |
| 448 | + | ... | ... |
scripts/cssens.py
| ... | ... | @@ -17,7 +17,7 @@ |
| 17 | 17 | # |
| 18 | 18 | # The source is modelled as a point source |
| 19 | 19 | # |
| 20 | -# Copyright (C) 2011 Jurgen Knodlseder | |
| 20 | +# Copyright (C) 2011-2014 Juergen Knoedlseder | |
| 21 | 21 | # |
| 22 | 22 | # This program is free software: you can redistribute it and/or modify |
| 23 | 23 | # it under the terms of the GNU General Public License as published by |
| ... | ... | @@ -45,682 +45,682 @@ import math |
| 45 | 45 | # cssens class # |
| 46 | 46 | # ============ # |
| 47 | 47 | class cssens(GApplication): |
| 48 | - """ | |
| 49 | - This class implements the sensitivity computation script. It derives | |
| 50 | - from the GammaLib::GApplication class which provides support for parameter | |
| 51 | - files, command line arguments, and logging. In that way the Python | |
| 52 | - script behaves just as a regular ctool. | |
| 53 | - """ | |
| 54 | - def __init__(self, *argv): | |
| 55 | - """ | |
| 56 | - Constructor. | |
| 57 | - """ | |
| 58 | - # Set name | |
| 59 | - self.name = "cssens" | |
| 60 | - self.version = "0.3.0" | |
| 61 | - | |
| 62 | - # Make sure that parfile exists | |
| 63 | - file = self.parfile() | |
| 64 | - | |
| 65 | - # Initialise application | |
| 66 | - if len(argv) == 0: | |
| 67 | - GApplication.__init__(self, self.name, self.version) | |
| 68 | - elif len(argv) ==1: | |
| 69 | - GApplication.__init__(self, self.name, self.version, *argv) | |
| 70 | - else: | |
| 71 | - raise TypeError("Invalid number of arguments given.") | |
| 72 | - | |
| 73 | - # Set logger properties | |
| 74 | - self.logFileOpen() | |
| 75 | - self.log_header() | |
| 76 | - self.log.date(True) | |
| 77 | - | |
| 78 | - # Return | |
| 79 | - return | |
| 80 | - | |
| 81 | - def __del__(self): | |
| 82 | - """ | |
| 83 | - Destructor. | |
| 84 | - """ | |
| 85 | - # Write separator into logger | |
| 86 | - if self.logTerse(): | |
| 87 | - self.log("\n") | |
| 88 | - | |
| 89 | - # Return | |
| 90 | - return | |
| 91 | - | |
| 92 | - def parfile(self): | |
| 93 | - """ | |
| 94 | - Check if parfile exists. If parfile does not exist then create a | |
| 95 | - default parfile. This kluge avoids shipping the cscript with a parfile. | |
| 96 | - """ | |
| 97 | - # Set parfile name | |
| 98 | - parfile = self.name+".par" | |
| 99 | - | |
| 100 | - try: | |
| 101 | - pars = GApplicationPars(parfile) | |
| 102 | - except: | |
| 103 | - # Signal if parfile was not found | |
| 104 | - sys.stdout.write("Parfile "+parfile+" not found. Create default parfile.\n") | |
| 105 | - | |
| 106 | - # Create default parfile | |
| 107 | - pars = GApplicationPars() | |
| 108 | - pars.append(GApplicationPar("outfile","f","h","sensitivity.dat","","","Output file name")) | |
| 109 | - pars.append(GApplicationPar("caldb","s","a","$GAMMALIB/share/caldb/cta","","","Calibration database")) | |
| 110 | - pars.append(GApplicationPar("irf","s","a","cta_dummy_irf","","","Instrument response function")) | |
| 111 | - pars.append(GApplicationPar("type","s","a","point","","","Source model type (point/gauss/shell/disk)")) | |
| 112 | - pars.append(GApplicationPar("offset","r","a","0.0","0.0","","Source offset angle (deg)")) | |
| 113 | - pars.append(GApplicationPar("bkg","s","a","$GAMMALIB/share/models/bkg_dummy.txt","","","Background model file function (none=power law for E)")) | |
| 114 | - pars.append(GApplicationPar("duration","r","a","180000.0","","","Effective exposure time (s)")) | |
| 115 | - pars.append(GApplicationPar("rad","r","a","5.0","","","Radius of ROI (deg)")) | |
| 116 | - pars.append(GApplicationPar("enumbins","i","h","0","","","Number of energy bins (0=unbinned)")) | |
| 117 | - pars.append(GApplicationPar("npix","i","h","200","","","Number of pixels for binned")) | |
| 118 | - pars.append(GApplicationPar("binsz","r","h","0.05","","","Pixel size for binned (deg/pixel)")) | |
| 119 | - pars.append(GApplicationPar("sigma","r","h","5.0","","","Significance threshold")) | |
| 120 | - pars.append(GApplicationPar("ts_use","b","h","yes","","","Use TS?")) | |
| 121 | - pars.append(GApplicationPar("index","r","h","-2.48","","","Assumed spectral index")) | |
| 122 | - pars.append(GApplicationPar("radius","r","h","0.1","","","Extended source model radius")) | |
| 123 | - pars.append(GApplicationPar("width","r","h","0.05","","","Extended source model width")) | |
| 124 | - pars.append(GApplicationPar("max_iter","i","h","50","","","Maximum number of iterations")) | |
| 125 | - pars.append(GApplicationPar("num_avg","i","h","3","","","Number of iterations for sliding average")) | |
| 126 | - pars.append_standard() | |
| 127 | - pars.save(parfile) | |
| 128 | - | |
| 129 | - # Return | |
| 130 | - return | |
| 131 | - | |
| 132 | - def get_parameters(self): | |
| 133 | - """ | |
| 134 | - Get parameters from parfile. | |
| 135 | - """ | |
| 136 | - # Get parameters | |
| 137 | - self.m_outfile = self["outfile"].filename() | |
| 138 | - self.m_caldb = self["caldb"].string() | |
| 139 | - self.m_irf = self["irf"].string() | |
| 140 | - self.m_type = self["type"].string() | |
| 141 | - self.m_offset = self["offset"].real() | |
| 142 | - self.m_bkg = self["bkg"].string() | |
| 143 | - self.m_duration = self["duration"].real() | |
| 144 | - self.m_roi = self["rad"].real() | |
| 145 | - self.m_nbins = self["enumbins"].integer() | |
| 146 | - self.m_npix = self["npix"].integer() | |
| 147 | - self.m_binsz = self["binsz"].real() | |
| 148 | - self.m_ts_thres = self["sigma"].real()*self["sigma"].real() | |
| 149 | - self.m_use_ts = self["ts_use"].boolean() | |
| 150 | - self.m_index = self["index"].real() | |
| 151 | - self.m_radius = self["radius"].real() | |
| 152 | - self.m_width = self["width"].real() | |
| 153 | - self.m_max_iter = self["max_iter"].integer() | |
| 154 | - self.m_num_avg = self["num_avg"].integer() | |
| 155 | - | |
| 156 | - # Set some fixed parameters | |
| 157 | - self.m_log = False # Logging in client tools | |
| 158 | - self.m_debug = False # Debugging in client tools | |
| 159 | - | |
| 160 | - # Return | |
| 161 | - return | |
| 162 | - | |
| 163 | - def execute(self): | |
| 164 | - """ | |
| 165 | - Execute the script. | |
| 166 | - """ | |
| 167 | - # Run the script | |
| 168 | - self.run() | |
| 169 | - | |
| 170 | - # Return | |
| 171 | - return | |
| 172 | - | |
| 173 | - def run(self): | |
| 174 | - """ | |
| 175 | - Run the script. | |
| 176 | - """ | |
| 177 | - # Switch screen logging on in debug mode | |
| 178 | - if self.logDebug(): | |
| 179 | - self.log.cout(True) | |
| 180 | - | |
| 181 | - # Get parameters | |
| 182 | - self.get_parameters() | |
| 183 | - | |
| 184 | - # Write input parameters into logger | |
| 185 | - if self.logTerse(): | |
| 186 | - self.log_parameters() | |
| 187 | - self.log("\n") | |
| 188 | - | |
| 189 | - # Initialise script | |
| 190 | - colnames = ['loge', 'emin', 'emax', 'crab', 'pflux', 'eflux', 'diffSens'] | |
| 191 | - results = [] | |
| 192 | - | |
| 193 | - # Initialise models. Note that we centre the point source at the Galactic | |
| 194 | - # center as our observation is also centred at the Galactic centre, so | |
| 195 | - # we're onaxis. | |
| 196 | - bkg_model = GModels() | |
| 197 | - full_model = GModels() | |
| 198 | - bkg_model.append(self.set_bkg_model()) | |
| 199 | - full_model.append(self.set_bkg_model()) | |
| 200 | - full_model.append(self.set_src_model(0.0, \ | |
| 201 | - self.m_offset, \ | |
| 202 | - type=self.m_type, \ | |
| 203 | - index=self.m_index)) | |
| 204 | - | |
| 205 | - # Write models into logger | |
| 206 | - if self.logTerse(): | |
| 207 | - self.log("\n") | |
| 208 | - self.log.header1("Models") | |
| 209 | - self.log.header2("Background model") | |
| 210 | - self.log(str(bkg_model)) | |
| 211 | - self.log("\n\n") | |
| 212 | - self.log.header2("Full model") | |
| 213 | - self.log(str(full_model)) | |
| 214 | - self.log("\n") | |
| 215 | - | |
| 216 | - # Write heder | |
| 217 | - if self.logTerse(): | |
| 218 | - self.log("\n") | |
| 219 | - self.log.header1("Sensitivity determination") | |
| 220 | - | |
| 221 | - # Loop over energy bands. The number of energy band is still | |
| 222 | - # fixed ... | |
| 223 | - for ieng in range(21): | |
| 224 | - | |
| 225 | - # Set energies | |
| 226 | - loge = -1.7 + ieng * 0.2 | |
| 227 | - emean = pow(10.0, loge) | |
| 228 | - emin = pow(10.0, loge-0.1) | |
| 229 | - emax = pow(10.0, loge+0.1) | |
| 230 | - | |
| 231 | - # Setup observation(s) | |
| 232 | - obs = self.set_obs(emin=emin, emax=emax) | |
| 233 | - | |
| 234 | - # Determine sensitivity | |
| 235 | - result = self.get_sensitivity(obs, bkg_model, full_model) | |
| 236 | - | |
| 237 | - # Write results | |
| 238 | - if ieng == 0: | |
| 239 | - f = open(self.m_outfile, 'w') | |
| 240 | - writer = csv.DictWriter(f, colnames) | |
| 241 | - writer.writerow(dict((_,_) for _ in colnames)) | |
| 242 | - writer.writerow(result) | |
| 243 | - f.close() | |
| 244 | - else: | |
| 245 | - f = open(self.m_outfile, 'a') | |
| 246 | - writer = csv.DictWriter(f, colnames) | |
| 247 | - writer.writerow(result) | |
| 248 | - f.close() | |
| 249 | - | |
| 250 | - # Append results | |
| 251 | - results.append(result) | |
| 252 | - | |
| 253 | - # Return | |
| 254 | - return | |
| 255 | - | |
| 256 | - def set_obs(self, lpnt=0.0, bpnt=0.0, emin=0.1, emax=100.0): | |
| 257 | - """ | |
| 258 | - Returns an observation container with a single CTA observation. | |
| 259 | - | |
| 260 | - Keywords: | |
| 261 | - lpnt - Galactic longitude of pointing [deg] (default: 0.0) | |
| 262 | - bpnt - Galactic latitude of pointing [deg] (default: 0.0) | |
| 263 | - emin - Minimum energy [TeV] (default: 0.1) | |
| 264 | - emax - Maximum energy [TeV] (default: 100.0) | |
| 265 | - """ | |
| 266 | - # Allocate observation container | |
| 267 | - obs = GObservations() | |
| 268 | - | |
| 269 | - # Set single pointing | |
| 270 | - pntdir = GSkyDir() | |
| 271 | - pntdir.lb_deg(lpnt, bpnt) | |
| 272 | - | |
| 273 | - # Create CTA observation | |
| 274 | - run = obsutils.set(pntdir, caldb=self.m_caldb, irf=self.m_irf, \ | |
| 275 | - duration=self.m_duration, \ | |
| 48 | + """ | |
| 49 | + This class implements the sensitivity computation script. It derives | |
| 50 | + from the GammaLib::GApplication class which provides support for parameter | |
| 51 | + files, command line arguments, and logging. In that way the Python | |
| 52 | + script behaves just as a regular ctool. | |
| 53 | + """ | |
| 54 | + def __init__(self, *argv): | |
| 55 | + """ | |
| 56 | + Constructor. | |
| 57 | + """ | |
| 58 | + # Set name | |
| 59 | + self.name = "cssens" | |
| 60 | + self.version = "0.3.0" | |
| 61 | + | |
| 62 | + # Make sure that parfile exists | |
| 63 | + file = self.parfile() | |
| 64 | + | |
| 65 | + # Initialise application | |
| 66 | + if len(argv) == 0: | |
| 67 | + GApplication.__init__(self, self.name, self.version) | |
| 68 | + elif len(argv) ==1: | |
| 69 | + GApplication.__init__(self, self.name, self.version, *argv) | |
| 70 | + else: | |
| 71 | + raise TypeError("Invalid number of arguments given.") | |
| 72 | + | |
| 73 | + # Set logger properties | |
| 74 | + self.logFileOpen() | |
| 75 | + self.log_header() | |
| 76 | + self.log.date(True) | |
| 77 | + | |
| 78 | + # Return | |
| 79 | + return | |
| 80 | + | |
| 81 | + def __del__(self): | |
| 82 | + """ | |
| 83 | + Destructor. | |
| 84 | + """ | |
| 85 | + # Write separator into logger | |
| 86 | + if self.logTerse(): | |
| 87 | + self.log("\n") | |
| 88 | + | |
| 89 | + # Return | |
| 90 | + return | |
| 91 | + | |
| 92 | + def parfile(self): | |
| 93 | + """ | |
| 94 | + Check if parfile exists. If parfile does not exist then create a | |
| 95 | + default parfile. This kluge avoids shipping the cscript with a parfile. | |
| 96 | + """ | |
| 97 | + # Set parfile name | |
| 98 | + parfile = self.name+".par" | |
| 99 | + | |
| 100 | + try: | |
| 101 | + pars = GApplicationPars(parfile) | |
| 102 | + except: | |
| 103 | + # Signal if parfile was not found | |
| 104 | + sys.stdout.write("Parfile "+parfile+" not found. Create default parfile.\n") | |
| 105 | + | |
| 106 | + # Create default parfile | |
| 107 | + pars = GApplicationPars() | |
| 108 | + pars.append(GApplicationPar("outfile","f","h","sensitivity.dat","","","Output file name")) | |
| 109 | + pars.append(GApplicationPar("caldb","s","a","$GAMMALIB/share/caldb/cta","","","Calibration database")) | |
| 110 | + pars.append(GApplicationPar("irf","s","a","cta_dummy_irf","","","Instrument response function")) | |
| 111 | + pars.append(GApplicationPar("type","s","a","point","","","Source model type (point/gauss/shell/disk)")) | |
| 112 | + pars.append(GApplicationPar("offset","r","a","0.0","0.0","","Source offset angle (deg)")) | |
| 113 | + pars.append(GApplicationPar("bkg","s","a","$GAMMALIB/share/models/bkg_dummy.txt","","","Background model file function (none=power law for E)")) | |
| 114 | + pars.append(GApplicationPar("duration","r","a","180000.0","","","Effective exposure time (s)")) | |
| 115 | + pars.append(GApplicationPar("rad","r","a","5.0","","","Radius of ROI (deg)")) | |
| 116 | + pars.append(GApplicationPar("enumbins","i","h","0","","","Number of energy bins (0=unbinned)")) | |
| 117 | + pars.append(GApplicationPar("npix","i","h","200","","","Number of pixels for binned")) | |
| 118 | + pars.append(GApplicationPar("binsz","r","h","0.05","","","Pixel size for binned (deg/pixel)")) | |
| 119 | + pars.append(GApplicationPar("sigma","r","h","5.0","","","Significance threshold")) | |
| 120 | + pars.append(GApplicationPar("ts_use","b","h","yes","","","Use TS?")) | |
| 121 | + pars.append(GApplicationPar("index","r","h","-2.48","","","Assumed spectral index")) | |
| 122 | + pars.append(GApplicationPar("radius","r","h","0.1","","","Extended source model radius")) | |
| 123 | + pars.append(GApplicationPar("width","r","h","0.05","","","Extended source model width")) | |
| 124 | + pars.append(GApplicationPar("max_iter","i","h","50","","","Maximum number of iterations")) | |
| 125 | + pars.append(GApplicationPar("num_avg","i","h","3","","","Number of iterations for sliding average")) | |
| 126 | + pars.append_standard() | |
| 127 | + pars.save(parfile) | |
| 128 | + | |
| 129 | + # Return | |
| 130 | + return | |
| 131 | + | |
| 132 | + def get_parameters(self): | |
| 133 | + """ | |
| 134 | + Get parameters from parfile. | |
| 135 | + """ | |
| 136 | + # Get parameters | |
| 137 | + self.m_outfile = self["outfile"].filename() | |
| 138 | + self.m_caldb = self["caldb"].string() | |
| 139 | + self.m_irf = self["irf"].string() | |
| 140 | + self.m_type = self["type"].string() | |
| 141 | + self.m_offset = self["offset"].real() | |
| 142 | + self.m_bkg = self["bkg"].string() | |
| 143 | + self.m_duration = self["duration"].real() | |
| 144 | + self.m_roi = self["rad"].real() | |
| 145 | + self.m_nbins = self["enumbins"].integer() | |
| 146 | + self.m_npix = self["npix"].integer() | |
| 147 | + self.m_binsz = self["binsz"].real() | |
| 148 | + self.m_ts_thres = self["sigma"].real()*self["sigma"].real() | |
| 149 | + self.m_use_ts = self["ts_use"].boolean() | |
| 150 | + self.m_index = self["index"].real() | |
| 151 | + self.m_radius = self["radius"].real() | |
| 152 | + self.m_width = self["width"].real() | |
| 153 | + self.m_max_iter = self["max_iter"].integer() | |
| 154 | + self.m_num_avg = self["num_avg"].integer() | |
| 155 | + | |
| 156 | + # Set some fixed parameters | |
| 157 | + self.m_log = False # Logging in client tools | |
| 158 | + self.m_debug = False # Debugging in client tools | |
| 159 | + | |
| 160 | + # Return | |
| 161 | + return | |
| 162 | + | |
| 163 | + def execute(self): | |
| 164 | + """ | |
| 165 | + Execute the script. | |
| 166 | + """ | |
| 167 | + # Run the script | |
| 168 | + self.run() | |
| 169 | + | |
| 170 | + # Return | |
| 171 | + return | |
| 172 | + | |
| 173 | + def run(self): | |
| 174 | + """ | |
| 175 | + Run the script. | |
| 176 | + """ | |
| 177 | + # Switch screen logging on in debug mode | |
| 178 | + if self.logDebug(): | |
| 179 | + self.log.cout(True) | |
| 180 | + | |
| 181 | + # Get parameters | |
| 182 | + self.get_parameters() | |
| 183 | + | |
| 184 | + # Write input parameters into logger | |
| 185 | + if self.logTerse(): | |
| 186 | + self.log_parameters() | |
| 187 | + self.log("\n") | |
| 188 | + | |
| 189 | + # Initialise script | |
| 190 | + colnames = ['loge', 'emin', 'emax', 'crab', 'pflux', 'eflux', 'diffSens'] | |
| 191 | + results = [] | |
| 192 | + | |
| 193 | + # Initialise models. Note that we centre the point source at the Galactic | |
| 194 | + # center as our observation is also centred at the Galactic centre, so | |
| 195 | + # we're onaxis. | |
| 196 | + bkg_model = GModels() | |
| 197 | + full_model = GModels() | |
| 198 | + bkg_model.append(self.set_bkg_model()) | |
| 199 | + full_model.append(self.set_bkg_model()) | |
| 200 | + full_model.append(self.set_src_model(0.0, \ | |
| 201 | + self.m_offset, \ | |
| 202 | + type=self.m_type, \ | |
| 203 | + index=self.m_index)) | |
| 204 | + | |
| 205 | + # Write models into logger | |
| 206 | + if self.logTerse(): | |
| 207 | + self.log("\n") | |
| 208 | + self.log.header1("Models") | |
| 209 | + self.log.header2("Background model") | |
| 210 | + self.log(str(bkg_model)) | |
| 211 | + self.log("\n\n") | |
| 212 | + self.log.header2("Full model") | |
| 213 | + self.log(str(full_model)) | |
| 214 | + self.log("\n") | |
| 215 | + | |
| 216 | + # Write heder | |
| 217 | + if self.logTerse(): | |
| 218 | + self.log("\n") | |
| 219 | + self.log.header1("Sensitivity determination") | |
| 220 | + | |
| 221 | + # Loop over energy bands. The number of energy band is still | |
| 222 | + # fixed ... | |
| 223 | + for ieng in range(21): | |
| 224 | + | |
| 225 | + # Set energies | |
| 226 | + loge = -1.7 + ieng * 0.2 | |
| 227 | + emean = pow(10.0, loge) | |
| 228 | + emin = pow(10.0, loge-0.1) | |
| 229 | + emax = pow(10.0, loge+0.1) | |
| 230 | + | |
| 231 | + # Setup observation(s) | |
| 232 | + obs = self.set_obs(emin=emin, emax=emax) | |
| 233 | + | |
| 234 | + # Determine sensitivity | |
| 235 | + result = self.get_sensitivity(obs, bkg_model, full_model) | |
| 236 | + | |
| 237 | + # Write results | |
| 238 | + if ieng == 0: | |
| 239 | + f = open(self.m_outfile, 'w') | |
| 240 | + writer = csv.DictWriter(f, colnames) | |
| 241 | + writer.writerow(dict((_,_) for _ in colnames)) | |
| 242 | + writer.writerow(result) | |
| 243 | + f.close() | |
| 244 | + else: | |
| 245 | + f = open(self.m_outfile, 'a') | |
| 246 | + writer = csv.DictWriter(f, colnames) | |
| 247 | + writer.writerow(result) | |
| 248 | + f.close() | |
| 249 | + | |
| 250 | + # Append results | |
| 251 | + results.append(result) | |
| 252 | + | |
| 253 | + # Return | |
| 254 | + return | |
| 255 | + | |
| 256 | + def set_obs(self, lpnt=0.0, bpnt=0.0, emin=0.1, emax=100.0): | |
| 257 | + """ | |
| 258 | + Returns an observation container with a single CTA observation. | |
| 259 | + | |
| 260 | + Keywords: | |
| 261 | + lpnt - Galactic longitude of pointing [deg] (default: 0.0) | |
| 262 | + bpnt - Galactic latitude of pointing [deg] (default: 0.0) | |
| 263 | + emin - Minimum energy [TeV] (default: 0.1) | |
| 264 | + emax - Maximum energy [TeV] (default: 100.0) | |
| 265 | + """ | |
| 266 | + # Allocate observation container | |
| 267 | + obs = GObservations() | |
| 268 | + | |
| 269 | + # Set single pointing | |
| 270 | + pntdir = GSkyDir() | |
| 271 | + pntdir.lb_deg(lpnt, bpnt) | |
| 272 | + | |
| 273 | + # Create CTA observation | |
| 274 | + run = obsutils.set(pntdir, caldb=self.m_caldb, irf=self.m_irf, \ | |
| 275 | + duration=self.m_duration, \ | |
| 276 | 276 | emin=emin, emax=emax, rad=self.m_roi) |
| 277 | - | |
| 278 | - # Append observation to container | |
| 279 | - obs.append(run) | |
| 280 | - | |
| 281 | - # Return observation container | |
| 282 | - return obs | |
| 283 | - | |
| 284 | - def set_bkg_model(self, fitidx=False): | |
| 285 | - """ | |
| 286 | - Setup standard CTA background model. We use a simple power law here, | |
| 287 | - scaled to Konrad's E configuration performance table. | |
| 288 | - | |
| 289 | - Keywords: | |
| 290 | - fitidx - Fit spectral index (default: False) | |
| 291 | - """ | |
| 292 | - # Define radial component | |
| 293 | - radial = GCTAModelRadialGauss(3.0) | |
| 294 | - | |
| 295 | - # Define spectral component. If a background model is given then | |
| 296 | - # use a file function. Otherwise use a static power law. | |
| 297 | - if len(self.m_bkg) > 0: | |
| 298 | - spectrum = GModelSpectralFunc(self.m_bkg, 1.0) | |
| 299 | - else: | |
| 300 | - spectrum = GModelSpectralPlaw(61.8e-6, -1.85, GEnergy(1.0, "TeV")) | |
| 301 | - if fitidx: | |
| 302 | - spectrum["Index"].free() | |
| 303 | - else: | |
| 304 | - spectrum["Index"].fix() | |
| 305 | - | |
| 306 | - # Create background model | |
| 307 | - model = GCTAModelRadialAcceptance(radial, spectrum) | |
| 308 | - model.name("Background") | |
| 309 | - model.instruments("CTA") | |
| 310 | - | |
| 311 | - # Return background model | |
| 312 | - return model | |
| 313 | - | |
| 314 | - def set_src_model(self, l, b, flux=1.0, index=-2.48, \ | |
| 277 | + | |
| 278 | + # Append observation to container | |
| 279 | + obs.append(run) | |
| 280 | + | |
| 281 | + # Return observation container | |
| 282 | + return obs | |
| 283 | + | |
| 284 | + def set_bkg_model(self, fitidx=False): | |
| 285 | + """ | |
| 286 | + Setup standard CTA background model. We use a simple power law here, | |
| 287 | + scaled to Konrad's E configuration performance table. | |
| 288 | + | |
| 289 | + Keywords: | |
| 290 | + fitidx - Fit spectral index (default: False) | |
| 291 | + """ | |
| 292 | + # Define radial component | |
| 293 | + radial = GCTAModelRadialGauss(3.0) | |
| 294 | + | |
| 295 | + # Define spectral component. If a background model is given then | |
| 296 | + # use a file function. Otherwise use a static power law. | |
| 297 | + if len(self.m_bkg) > 0: | |
| 298 | + spectrum = GModelSpectralFunc(self.m_bkg, 1.0) | |
| 299 | + else: | |
| 300 | + spectrum = GModelSpectralPlaw(61.8e-6, -1.85, GEnergy(1.0, "TeV")) | |
| 301 | + if fitidx: | |
| 302 | + spectrum["Index"].free() | |
| 303 | + else: | |
| 304 | + spectrum["Index"].fix() | |
| 305 | + | |
| 306 | + # Create background model | |
| 307 | + model = GCTAModelRadialAcceptance(radial, spectrum) | |
| 308 | + model.name("Background") | |
| 309 | + model.instruments("CTA") | |
| 310 | + | |
| 311 | + # Return background model | |
| 312 | + return model | |
| 313 | + | |
| 314 | + def set_src_model(self, l, b, flux=1.0, index=-2.48, \ | |
| 315 | 315 | type="point", fitpos=False, fitidx=False): |
| 316 | - """ | |
| 317 | - Returns a single source with Crab-like spectrum. The source flux | |
| 318 | - can be scaled in Crab units. The Crab spectrum is based on MAGIC | |
| 319 | - observations (Albert et al. 2008, ApJ, 674, 1037). | |
| 320 | - | |
| 321 | - Parameters: | |
| 322 | - l - Galactic longitude of source location [deg] | |
| 323 | - b - Galactic latitude of source location [deg] | |
| 324 | - Keywords: | |
| 325 | - flux - Source flux [Crabs] | |
| 326 | - index - Spectral index | |
| 327 | - type - Source type ("point", "gauss", "disk", "shell") | |
| 328 | - fitpos - Fit position and size? (default: False) | |
| 329 | - fitidx - Fit index? (default: False) | |
| 330 | - """ | |
| 331 | - # Set source location | |
| 332 | - location = GSkyDir() | |
| 333 | - location.lb_deg(l, b) | |
| 334 | - | |
| 335 | - # Set source spectrum | |
| 336 | - spectrum = GModelSpectralPlaw(flux*5.7e-16, index, GEnergy(0.3, "TeV") | |
| 337 | - if fitidx: | |
| 338 | - spectrum["Index"].free() | |
| 339 | - else: | |
| 340 | - spectrum["Index"].fix() | |
| 341 | - | |
| 342 | - # Set source | |
| 343 | - if type == "point": | |
| 344 | - spatial = GModelSpatialPointSource(location) | |
| 345 | - if fitpos: | |
| 346 | - spatial["RA"].free() | |
| 347 | - spatial["DEC"].free() | |
| 348 | - else: | |
| 349 | - spatial["RA"].fix() | |
| 350 | - spatial["DEC"].fix() | |
| 351 | - elif type == "gauss": | |
| 352 | - spatial = GModelSpatialRadialGauss(location, self.m_radius) | |
| 353 | - if fitpos: | |
| 354 | - spatial["RA"].free() | |
| 355 | - spatial["DEC"].free() | |
| 356 | - spatial["Sigma"].free() | |
| 357 | - else: | |
| 358 | - spatial["RA"].fix() | |
| 359 | - spatial["DEC"].fix() | |
| 360 | - spatial["Sigma"].fix() | |
| 361 | - elif type == "disk": | |
| 362 | - spatial = GModelSpatialRadialDisk(location, self.m_radius) | |
| 363 | - if fitpos: | |
| 364 | - spatial["RA"].free() | |
| 365 | - spatial["DEC"].free() | |
| 366 | - spatial["Radius"].free() | |
| 367 | - else: | |
| 368 | - spatial["RA"].fix() | |
| 369 | - spatial["DEC"].fix() | |
| 370 | - spatial["Radius"].fix() | |
| 371 | - elif type == "shell": | |
| 372 | - spatial = GModelSpatialRadialShell(location, self.m_radius, self.m_width) | |
| 373 | - if fitpos: | |
| 374 | - spatial["RA"].free() | |
| 375 | - spatial["DEC"].free() | |
| 376 | - spatial["Radius"].free() | |
| 377 | - spatial["Width"].free() | |
| 378 | - else: | |
| 379 | - spatial["RA"].fix() | |
| 380 | - spatial["DEC"].fix() | |
| 381 | - spatial["Radius"].fix() | |
| 382 | - spatial["Width"].fix() | |
| 383 | - else: | |
| 384 | - self.log("ERROR: Unknown source type '"+type+"'.\n") | |
| 385 | - return None | |
| 316 | + """ | |
| 317 | + Returns a single source with Crab-like spectrum. The source flux | |
| 318 | + can be scaled in Crab units. The Crab spectrum is based on MAGIC | |
| 319 | + observations (Albert et al. 2008, ApJ, 674, 1037). | |
| 320 | + | |
| 321 | + Parameters: | |
| 322 | + l - Galactic longitude of source location [deg] | |
| 323 | + b - Galactic latitude of source location [deg] | |
| 324 | + Keywords: | |
| 325 | + flux - Source flux [Crabs] | |
| 326 | + index - Spectral index | |
| 327 | + type - Source type ("point", "gauss", "disk", "shell") | |
| 328 | + fitpos - Fit position and size? (default: False) | |
| 329 | + fitidx - Fit index? (default: False) | |
| 330 | + """ | |
| 331 | + # Set source location | |
| 332 | + location = GSkyDir() | |
| 333 | + location.lb_deg(l, b) | |
| 334 | + | |
| 335 | + # Set source spectrum | |
| 336 | + spectrum = GModelSpectralPlaw(flux*5.7e-16, index, GEnergy(0.3, "TeV") | |
| 337 | + if fitidx: | |
| 338 | + spectrum["Index"].free() | |
| 339 | + else: | |
| 340 | + spectrum["Index"].fix() | |
| 341 | + | |
| 342 | + # Set source | |
| 343 | + if type == "point": | |
| 344 | + spatial = GModelSpatialPointSource(location) | |
| 345 | + if fitpos: | |
| 346 | + spatial["RA"].free() | |
| 347 | + spatial["DEC"].free() | |
| 348 | + else: | |
| 349 | + spatial["RA"].fix() | |
| 350 | + spatial["DEC"].fix() | |
| 351 | + elif type == "gauss": | |
| 352 | + spatial = GModelSpatialRadialGauss(location, self.m_radius) | |
| 353 | + if fitpos: | |
| 354 | + spatial["RA"].free() | |
| 355 | + spatial["DEC"].free() | |
| 356 | + spatial["Sigma"].free() | |
| 357 | + else: | |
| 358 | + spatial["RA"].fix() | |
| 359 | + spatial["DEC"].fix() | |
| 360 | + spatial["Sigma"].fix() | |
| 361 | + elif type == "disk": | |
| 362 | + spatial = GModelSpatialRadialDisk(location, self.m_radius) | |
| 363 | + if fitpos: | |
| 364 | + spatial["RA"].free() | |
| 365 | + spatial["DEC"].free() | |
| 366 | + spatial["Radius"].free() | |
| 367 | + else: | |
| 368 | + spatial["RA"].fix() | |
| 369 | + spatial["DEC"].fix() | |
| 370 | + spatial["Radius"].fix() | |
| 371 | + elif type == "shell": | |
| 372 | + spatial = GModelSpatialRadialShell(location, self.m_radius, self.m_width) | |
| 373 | + if fitpos: | |
| 374 | + spatial["RA"].free() | |
| 375 | + spatial["DEC"].free() | |
| 376 | + spatial["Radius"].free() | |
| 377 | + spatial["Width"].free() | |
| 378 | + else: | |
| 379 | + spatial["RA"].fix() | |
| 380 | + spatial["DEC"].fix() | |
| 381 | + spatial["Radius"].fix() | |
| 382 | + spatial["Width"].fix() | |
| 383 | + else: | |
| 384 | + self.log("ERROR: Unknown source type '"+type+"'.\n") | |
| 385 | + return None | |
| 386 | 386 | source = GModelSky(spatial, spectrum) |
| 387 | - | |
| 388 | - # Set source name | |
| 389 | - source.name("Test") | |
| 390 | - | |
| 391 | - # Return source | |
| 392 | - return source | |
| 393 | - | |
| 394 | - def get_sensitivity(self, obs, bkg_model, full_model): | |
| 395 | - """ | |
| 396 | - Determine sensitivity for a given observations. | |
| 397 | - | |
| 398 | - Parameters: | |
| 399 | - obs - Observation container | |
| 400 | - bkg_model - Background model | |
| 401 | - full_model - Source model | |
| 402 | - """ | |
| 403 | - # Set TeV->erg conversion factor | |
| 404 | - tev2erg = 1.6021764 | |
| 405 | - | |
| 406 | - # Determine energy boundaries from first observation in | |
| 407 | - # the container | |
| 408 | - for run in obs: | |
| 409 | - emin = run.events().ebounds().emin() | |
| 410 | - emax = run.events().ebounds().emax() | |
| 411 | - loge = math.log10(math.sqrt(emin.TeV()*emax.TeV())) | |
| 412 | - erg_mean = math.pow(10.0, loge) * tev2erg | |
| 413 | - erg_width = (emax.TeV()-emin.TeV()) * tev2erg | |
| 414 | - break | |
| 415 | - | |
| 416 | - # Write header | |
| 417 | - if self.logTerse(): | |
| 418 | - self.log("\n") | |
| 419 | - self.log.header2("Energies: "+str(emin)+" - "+str(emax)) | |
| 420 | - | |
| 421 | - # Initialise loop | |
| 422 | - flux_value = [] | |
| 423 | - pflux_value = [] | |
| 424 | - eflux_value = [] | |
| 425 | - diffSens_value = [] | |
| 426 | - iter = 0 | |
| 427 | - test_flux = 0.1 # This is the initial test flux in Crab units | |
| 428 | - | |
| 429 | - # Loop until we break | |
| 430 | - while True: | |
| 431 | - | |
| 432 | - # Update iteration counter | |
| 433 | - iter += 1 | |
| 434 | - | |
| 435 | - # Write header | |
| 436 | - if self.logExplicit(): | |
| 437 | - self.log.header2("Iteration "+str(iter)) | |
| 438 | - | |
| 439 | - # Set test flux | |
| 440 | - full_model["Test"]['Prefactor'].value(test_flux) | |
| 441 | - obs.models(full_model) | |
| 442 | - | |
| 443 | - # Simulate events | |
| 444 | - sim = obsutils.sim(obs, nbins=self.m_nbins, seed=iter, \ | |
| 445 | - binsz=self.m_binsz, npix=self.m_npix, \ | |
| 446 | - log=self.m_log, debug=self.m_debug) | |
| 447 | - | |
| 448 | - # Determine number of events in simulation | |
| 449 | - nevents = 0.0 | |
| 450 | - for run in sim: | |
| 451 | - nevents += run.events().number() | |
| 452 | - | |
| 453 | - # Write simulation results | |
| 454 | - if self.logExplicit(): | |
| 455 | - self.log.header3("Simulation") | |
| 456 | - self.log.parformat("Number of simulated events") | |
| 457 | - self.log(nevents) | |
| 458 | - self.log("\n") | |
| 459 | - | |
| 460 | - # Fit background only | |
| 461 | - sim.models(bkg_model) | |
| 462 | - like = obsutils.fit(sim, log=self.m_log, debug=self.m_debug) | |
| 463 | - result_bgm = like.obs().models().copy() | |
| 464 | - LogL_bgm = like.opt().value() | |
| 465 | - npred_bgm = like.obs().npred() | |
| 466 | - | |
| 467 | - # Assess quality based on a comparison between Npred and Nevents | |
| 468 | - quality_bgm = npred_bgm-nevents | |
| 469 | - | |
| 470 | - # Write background fit results | |
| 471 | - if self.logExplicit(): | |
| 472 | - self.log.header3("Background model fit") | |
| 473 | - self.log.parformat("log likelihood") | |
| 474 | - self.log(LogL_bgm) | |
| 475 | - self.log("\n") | |
| 476 | - self.log.parformat("Number of predicted events") | |
| 477 | - self.log(npred_bgm) | |
| 478 | - self.log("\n") | |
| 479 | - self.log.parformat("Fit quality") | |
| 480 | - self.log(quality_bgm) | |
| 481 | - self.log("\n") | |
| 482 | - | |
| 483 | - # Start over if the fit quality was bad | |
| 484 | - if abs(quality_bgm) > 3.0: | |
| 485 | - if self.logExplicit(): | |
| 486 | - self.log("Fit quality outside required range. Start over.\n") | |
| 487 | - continue | |
| 488 | - | |
| 489 | - # Write model fit results | |
| 490 | - if self.logExplicit(): | |
| 491 | - for model in result_bgm: | |
| 492 | - self.log.parformat("Model") | |
| 493 | - self.log(model.name()) | |
| 494 | - self.log("\n") | |
| 495 | - for par in model: | |
| 496 | - self.log(str(par)+"\n") | |
| 497 | - | |
| 498 | - # Fit background and test source | |
| 499 | - sim.models(full_model) | |
| 500 | - like = obsutils.fit(sim, log=self.m_log, debug=self.m_debug) | |
| 501 | - result_all = like.obs().models().copy() | |
| 502 | - LogL_all = like.opt().value() | |
| 503 | - npred_all = like.obs().npred() | |
| 504 | - ts = 2.0*(LogL_bgm-LogL_all) | |
| 505 | - | |
| 506 | - # Assess quality based on a comparison between Npred and Nevents | |
| 507 | - quality_all = npred_all-nevents | |
| 508 | - | |
| 509 | - # Write background and test source fit results | |
| 510 | - if self.logExplicit(): | |
| 511 | - self.log.header3("Background and test source model fit") | |
| 512 | - self.log.parformat("Test statistics") | |
| 513 | - self.log(ts) | |
| 514 | - self.log("\n") | |
| 515 | - self.log.parformat("log likelihood") | |
| 516 | - self.log(LogL_all) | |
| 517 | - self.log("\n") | |
| 518 | - self.log.parformat("Number of predicted events") | |
| 519 | - self.log(npred_all) | |
| 520 | - self.log("\n") | |
| 521 | - self.log.parformat("Fit quality") | |
| 522 | - self.log(quality_all) | |
| 523 | - self.log("\n") | |
| 524 | - # | |
| 525 | - for model in result_all: | |
| 526 | - self.log.parformat("Model") | |
| 527 | - self.log(model.name()) | |
| 528 | - self.log("\n") | |
| 529 | - for par in model: | |
| 530 | - self.log(str(par)+"\n") | |
| 531 | - | |
| 532 | - # Start over if the fit quality was bad | |
| 533 | - if abs(quality_all) > 3.0: | |
| 534 | - if self.logExplicit(): | |
| 535 | - self.log("Fit quality outside required range. Start over.\n") | |
| 536 | - continue | |
| 537 | - | |
| 538 | - # Start over if TS was non-positive | |
| 539 | - if ts <= 0.0: | |
| 540 | - if self.logExplicit(): | |
| 541 | - self.log("Non positive TS. Start over.\n") | |
| 542 | - continue | |
| 543 | - | |
| 544 | - # Get fitted Crab, photon and energy fluxes | |
| 545 | - cflux = result_all["Test"]['Prefactor'].value() | |
| 546 | - cflux_err = result_all["Test"]['Prefactor'].error() | |
| 547 | - pflux = result_all["Test"].spectral().flux(emin, emax) | |
| 548 | - eflux = result_all["Test"].spectral().eflux(emin, emax) | |
| 549 | - | |
| 550 | - # Compute differential sensitivity | |
| 551 | - diffSens = pflux / erg_width * erg_mean*erg_mean | |
| 552 | - | |
| 553 | - # Compute flux correction factor based on average TS | |
| 554 | - correct = 1.0 | |
| 555 | - if self.m_use_ts: | |
| 556 | - if ts > 0: | |
| 557 | - correct = math.sqrt(self.m_ts_thres/ts) | |
| 558 | - else: | |
| 559 | - if cflux > 0 and cflux_err > 0: | |
| 560 | - correct = math.sqrt(self.m_ts_thres)/(cflux/cflux_err) | |
| 561 | - | |
| 562 | - # Compute extrapolated fluxes | |
| 563 | - flux = correct * cflux | |
| 564 | - pflux = correct * pflux | |
| 565 | - eflux = correct * eflux | |
| 566 | - diffSens = correct * diffSens | |
| 567 | - flux_value.append(flux) | |
| 568 | - pflux_value.append(pflux) | |
| 569 | - eflux_value.append(eflux) | |
| 570 | - diffSens_value.append(diffSens) | |
| 571 | - | |
| 572 | - # Write background and test source fit results | |
| 573 | - if self.logExplicit(): | |
| 574 | - self.log.parformat("Photon flux") | |
| 575 | - self.log(pflux) | |
| 576 | - self.log(" ph/cm2/s\n") | |
| 577 | - self.log.parformat("Energy flux") | |
| 578 | - self.log(eflux) | |
| 579 | - self.log(" erg/cm2/s\n") | |
| 580 | - self.log.parformat("Crab flux") | |
| 581 | - self.log(cflux*1000.0) | |
| 582 | - self.log(" mCrab\n") | |
| 583 | - self.log.parformat("Differential sensitivity") | |
| 584 | - self.log(diffSens) | |
| 585 | - self.log(" erg/cm2/s\n") | |
| 586 | - for model in result_all: | |
| 587 | - self.log.parformat("Model") | |
| 588 | - self.log(model.name()) | |
| 589 | - self.log("\n") | |
| 590 | - for par in model: | |
| 591 | - self.log(str(par)+"\n") | |
| 592 | - elif self.logTerse(): | |
| 593 | - self.log.parformat("Iteration "+str(iter)) | |
| 594 | - self.log("TS=") | |
| 595 | - self.log(ts) | |
| 596 | - self.log(" ") | |
| 597 | - self.log("corr=") | |
| 598 | - self.log(correct) | |
| 599 | - self.log(" ") | |
| 600 | - self.log(pflux) | |
| 601 | - self.log(" ph/cm2/s = ") | |
| 602 | - self.log(eflux) | |
| 603 | - self.log(" erg/cm2/s = ") | |
| 604 | - self.log(cflux*1000.0) | |
| 605 | - self.log(" mCrab = ") | |
| 606 | - self.log(diffSens) | |
| 607 | - self.log(" erg/cm2/s\n") | |
| 608 | - | |
| 609 | - # Compute sliding average of extrapolated fitted prefactor, | |
| 610 | - # photon and energy flux. This damps out fluctuations and | |
| 611 | - # improves convergence | |
| 612 | - flux = 0.0 | |
| 613 | - pflux = 0.0 | |
| 614 | - eflux = 0.0 | |
| 615 | - diffSens = 0.0 | |
| 616 | - num = 0.0 | |
| 617 | - for k in range(self.m_num_avg): | |
| 618 | - inx = len(flux_value) - k - 1 | |
| 619 | - if inx >= 0: | |
| 620 | - flux += flux_value[inx] | |
| 621 | - pflux += pflux_value[inx] | |
| 622 | - eflux += eflux_value[inx] | |
| 623 | - diffSens += diffSens_value[inx] | |
| 624 | - num += 1.0 | |
| 625 | - flux /= num | |
| 626 | - pflux /= num | |
| 627 | - eflux /= num | |
| 628 | - diffSens /= num | |
| 629 | - | |
| 630 | - # Compare average flux to last average | |
| 631 | - if iter > self.m_num_avg: | |
| 632 | - if test_flux > 0: | |
| 633 | - ratio = flux/test_flux | |
| 634 | - | |
| 635 | - # We have 2 convergence criteria: | |
| 636 | - # 1. The average flux does not change | |
| 637 | - # 2. The flux correction factor is small | |
| 638 | - if ratio >= 0.99 and ratio <= 1.01 and \ | |
| 639 | - correct >= 0.9 and correct <= 1.1: | |
| 640 | - if self.logTerse(): | |
| 641 | - self.log(" Converged ("+str(ratio)+")\n") | |
| 642 | - break | |
| 643 | - else: | |
| 644 | - if self.logTerse(): | |
| 645 | - self.log(" Flux is zero.\n") | |
| 646 | - break | |
| 647 | - | |
| 648 | - # Use average for next iteration | |
| 649 | - test_flux = flux | |
| 650 | - | |
| 651 | - # Exit loop if number of trials exhausted | |
| 652 | - if (iter >= self.m_max_iter): | |
| 653 | - if self.logTerse(): | |
| 654 | - self.log(" Test ended after "+str(self.m_max_iter)+" iterations.\n") | |
| 655 | - break | |
| 656 | - | |
| 657 | - # Write fit results | |
| 658 | - if self.logTerse(): | |
| 659 | - self.log.header3("Fit results") | |
| 660 | - self.log.parformat("Test statistics") | |
| 661 | - self.log(ts) | |
| 662 | - self.log("\n") | |
| 663 | - self.log.parformat("Photon flux") | |
| 664 | - self.log(pflux) | |
| 665 | - self.log(" ph/cm2/s\n") | |
| 666 | - self.log.parformat("Energy flux") | |
| 667 | - self.log(eflux) | |
| 668 | - self.log(" erg/cm2/s\n") | |
| 669 | - self.log.parformat("Crab flux") | |
| 670 | - self.log(cflux*1000.0) | |
| 671 | - self.log(" mCrab\n") | |
| 672 | - self.log.parformat("Differential sensitivity") | |
| 673 | - self.log(diffSens) | |
| 674 | - self.log(" erg/cm2/s\n") | |
| 675 | - self.log.parformat("Number of simulated events") | |
| 676 | - self.log(nevents) | |
| 677 | - self.log("\n") | |
| 678 | - self.log.header3("Background and test source model fitting") | |
| 679 | - self.log.parformat("log likelihood") | |
| 680 | - self.log(LogL_all) | |
| 681 | - self.log("\n") | |
| 682 | - self.log.parformat("Number of predicted events") | |
| 683 | - self.log(npred_all) | |
| 684 | - self.log("\n") | |
| 685 | - for model in result_all: | |
| 686 | - self.log.parformat("Model") | |
| 687 | - self.log(model.name()) | |
| 688 | - self.log("\n") | |
| 689 | - for par in model: | |
| 690 | - self.log(str(par)+"\n") | |
| 691 | - self.log.header3("Background model fit") | |
| 692 | - self.log.parformat("log likelihood") | |
| 693 | - self.log(LogL_bgm) | |
| 694 | - self.log("\n") | |
| 695 | - self.log.parformat("Number of predicted events") | |
| 696 | - self.log(npred_bgm) | |
| 697 | - self.log("\n") | |
| 698 | - for model in result_bgm: | |
| 699 | - self.log.parformat("Model") | |
| 700 | - self.log(model.name()) | |
| 701 | - self.log("\n") | |
| 702 | - for par in model: | |
| 703 | - self.log(str(par)+"\n") | |
| 704 | - | |
| 705 | - # Store result | |
| 706 | - result = {'loge': loge, 'emin': emin.TeV(), 'emax': emax.TeV(), \ | |
| 707 | - 'crab': flux, 'pflux': pflux, 'eflux': eflux, \ | |
| 708 | - 'diffSens': diffSens} | |
| 709 | - | |
| 710 | - # Return result | |
| 711 | - return result | |
| 387 | + | |
| 388 | + # Set source name | |
| 389 | + source.name("Test") | |
| 390 | + | |
| 391 | + # Return source | |
| 392 | + return source | |
| 393 | + | |
| 394 | + def get_sensitivity(self, obs, bkg_model, full_model): | |
| 395 | + """ | |
| 396 | + Determine sensitivity for a given observations. | |
| 397 | + | |
| 398 | + Parameters: | |
| 399 | + obs - Observation container | |
| 400 | + bkg_model - Background model | |
| 401 | + full_model - Source model | |
| 402 | + """ | |
| 403 | + # Set TeV->erg conversion factor | |
| 404 | + tev2erg = 1.6021764 | |
| 405 | + | |
| 406 | + # Determine energy boundaries from first observation in | |
| 407 | + # the container | |
| 408 | + for run in obs: | |
| 409 | + emin = run.events().ebounds().emin() | |
| 410 | + emax = run.events().ebounds().emax() | |
| 411 | + loge = math.log10(math.sqrt(emin.TeV()*emax.TeV())) | |
| 412 | + erg_mean = math.pow(10.0, loge) * tev2erg | |
| 413 | + erg_width = (emax.TeV()-emin.TeV()) * tev2erg | |
| 414 | + break | |
| 415 | + | |
| 416 | + # Write header | |
| 417 | + if self.logTerse(): | |
| 418 | + self.log("\n") | |
| 419 | + self.log.header2("Energies: "+str(emin)+" - "+str(emax)) | |
| 420 | + | |
| 421 | + # Initialise loop | |
| 422 | + flux_value = [] | |
| 423 | + pflux_value = [] | |
| 424 | + eflux_value = [] | |
| 425 | + diffSens_value = [] | |
| 426 | + iter = 0 | |
| 427 | + test_flux = 0.1 # This is the initial test flux in Crab units | |
| 428 | + | |
| 429 | + # Loop until we break | |
| 430 | + while True: | |
| 431 | + | |
| 432 | + # Update iteration counter | |
| 433 | + iter += 1 | |
| 434 | + | |
| 435 | + # Write header | |
| 436 | + if self.logExplicit(): | |
| 437 | + self.log.header2("Iteration "+str(iter)) | |
| 438 | + | |
| 439 | + # Set test flux | |
| 440 | + full_model["Test"]['Prefactor'].value(test_flux) | |
| 441 | + obs.models(full_model) | |
| 442 | + | |
| 443 | + # Simulate events | |
| 444 | + sim = obsutils.sim(obs, nbins=self.m_nbins, seed=iter, \ | |
| 445 | + binsz=self.m_binsz, npix=self.m_npix, \ | |
| 446 | + log=self.m_log, debug=self.m_debug) | |
| 447 | + | |
| 448 | + # Determine number of events in simulation | |
| 449 | + nevents = 0.0 | |
| 450 | + for run in sim: | |
| 451 | + nevents += run.events().number() | |
| 452 | + | |
| 453 | + # Write simulation results | |
| 454 | + if self.logExplicit(): | |
| 455 | + self.log.header3("Simulation") | |
| 456 | + self.log.parformat("Number of simulated events") | |
| 457 | + self.log(nevents) | |
| 458 | + self.log("\n") | |
| 459 | + | |
| 460 | + # Fit background only | |
| 461 | + sim.models(bkg_model) | |
| 462 | + like = obsutils.fit(sim, log=self.m_log, debug=self.m_debug) | |
| 463 | + result_bgm = like.obs().models().copy() | |
| 464 | + LogL_bgm = like.opt().value() | |
| 465 | + npred_bgm = like.obs().npred() | |
| 466 | + | |
| 467 | + # Assess quality based on a comparison between Npred and Nevents | |
| 468 | + quality_bgm = npred_bgm-nevents | |
| 469 | + | |
| 470 | + # Write background fit results | |
| 471 | + if self.logExplicit(): | |
| 472 | + self.log.header3("Background model fit") | |
| 473 | + self.log.parformat("log likelihood") | |
| 474 | + self.log(LogL_bgm) | |
| 475 | + self.log("\n") | |
| 476 | + self.log.parformat("Number of predicted events") | |
| 477 | + self.log(npred_bgm) | |
| 478 | + self.log("\n") | |
| 479 | + self.log.parformat("Fit quality") | |
| 480 | + self.log(quality_bgm) | |
| 481 | + self.log("\n") | |
| 482 | + | |
| 483 | + # Start over if the fit quality was bad | |
| 484 | + if abs(quality_bgm) > 3.0: | |
| 485 | + if self.logExplicit(): | |
| 486 | + self.log("Fit quality outside required range. Start over.\n") | |
| 487 | + continue | |
| 488 | + | |
| 489 | + # Write model fit results | |
| 490 | + if self.logExplicit(): | |
| 491 | + for model in result_bgm: | |
| 492 | + self.log.parformat("Model") | |
| 493 | + self.log(model.name()) | |
| 494 | + self.log("\n") | |
| 495 | + for par in model: | |
| 496 | + self.log(str(par)+"\n") | |
| 497 | + | |
| 498 | + # Fit background and test source | |
| 499 | + sim.models(full_model) | |
| 500 | + like = obsutils.fit(sim, log=self.m_log, debug=self.m_debug) | |
| 501 | + result_all = like.obs().models().copy() | |
| 502 | + LogL_all = like.opt().value() | |
| 503 | + npred_all = like.obs().npred() | |
| 504 | + ts = 2.0*(LogL_bgm-LogL_all) | |
| 505 | + | |
| 506 | + # Assess quality based on a comparison between Npred and Nevents | |
| 507 | + quality_all = npred_all-nevents | |
| 508 | + | |
| 509 | + # Write background and test source fit results | |
| 510 | + if self.logExplicit(): | |
| 511 | + self.log.header3("Background and test source model fit") | |
| 512 | + self.log.parformat("Test statistics") | |
| 513 | + self.log(ts) | |
| 514 | + self.log("\n") | |
| 515 | + self.log.parformat("log likelihood") | |
| 516 | + self.log(LogL_all) | |
| 517 | + self.log("\n") | |
| 518 | + self.log.parformat("Number of predicted events") | |
| 519 | + self.log(npred_all) | |
| 520 | + self.log("\n") | |
| 521 | + self.log.parformat("Fit quality") | |
| 522 | + self.log(quality_all) | |
| 523 | + self.log("\n") | |
| 524 | + # | |
| 525 | + for model in result_all: | |
| 526 | + self.log.parformat("Model") | |
| 527 | + self.log(model.name()) | |
| 528 | + self.log("\n") | |
| 529 | + for par in model: | |
| 530 | + self.log(str(par)+"\n") | |
| 531 | + | |
| 532 | + # Start over if the fit quality was bad | |
| 533 | + if abs(quality_all) > 3.0: | |
| 534 | + if self.logExplicit(): | |
| 535 | + self.log("Fit quality outside required range. Start over.\n") | |
| 536 | + continue | |
| 537 | + | |
| 538 | + # Start over if TS was non-positive | |
| 539 | + if ts <= 0.0: | |
| 540 | + if self.logExplicit(): | |
| 541 | + self.log("Non positive TS. Start over.\n") | |
| 542 | + continue | |
| 543 | + | |
| 544 | + # Get fitted Crab, photon and energy fluxes | |
| 545 | + cflux = result_all["Test"]['Prefactor'].value() | |
| 546 | + cflux_err = result_all["Test"]['Prefactor'].error() | |
| 547 | + pflux = result_all["Test"].spectral().flux(emin, emax) | |
| 548 | + eflux = result_all["Test"].spectral().eflux(emin, emax) | |
| 549 | + | |
| 550 | + # Compute differential sensitivity | |
| 551 | + diffSens = pflux / erg_width * erg_mean*erg_mean | |
| 552 | + | |
| 553 | + # Compute flux correction factor based on average TS | |
| 554 | + correct = 1.0 | |
| 555 | + if self.m_use_ts: | |
| 556 | + if ts > 0: | |
| 557 | + correct = math.sqrt(self.m_ts_thres/ts) | |
| 558 | + else: | |
| 559 | + if cflux > 0 and cflux_err > 0: | |
| 560 | + correct = math.sqrt(self.m_ts_thres)/(cflux/cflux_err) | |
| 561 | + | |
| 562 | + # Compute extrapolated fluxes | |
| 563 | + flux = correct * cflux | |
| 564 | + pflux = correct * pflux | |
| 565 | + eflux = correct * eflux | |
| 566 | + diffSens = correct * diffSens | |
| 567 | + flux_value.append(flux) | |
| 568 | + pflux_value.append(pflux) | |
| 569 | + eflux_value.append(eflux) | |
| 570 | + diffSens_value.append(diffSens) | |
| 571 | + | |
| 572 | + # Write background and test source fit results | |
| 573 | + if self.logExplicit(): | |
| 574 | + self.log.parformat("Photon flux") | |
| 575 | + self.log(pflux) | |
| 576 | + self.log(" ph/cm2/s\n") | |
| 577 | + self.log.parformat("Energy flux") | |
| 578 | + self.log(eflux) | |
| 579 | + self.log(" erg/cm2/s\n") | |
| 580 | + self.log.parformat("Crab flux") | |
| 581 | + self.log(cflux*1000.0) | |
| 582 | + self.log(" mCrab\n") | |
| 583 | + self.log.parformat("Differential sensitivity") | |
| 584 | + self.log(diffSens) | |
| 585 | + self.log(" erg/cm2/s\n") | |
| 586 | + for model in result_all: | |
| 587 | + self.log.parformat("Model") | |
| 588 | + self.log(model.name()) | |
| 589 | + self.log("\n") | |
| 590 | + for par in model: | |
| 591 | + self.log(str(par)+"\n") | |
| 592 | + elif self.logTerse(): | |
| 593 | + self.log.parformat("Iteration "+str(iter)) | |
| 594 | + self.log("TS=") | |
| 595 | + self.log(ts) | |
| 596 | + self.log(" ") | |
| 597 | + self.log("corr=") | |
| 598 | + self.log(correct) | |
| 599 | + self.log(" ") | |
| 600 | + self.log(pflux) | |
| 601 | + self.log(" ph/cm2/s = ") | |
| 602 | + self.log(eflux) | |
| 603 | + self.log(" erg/cm2/s = ") | |
| 604 | + self.log(cflux*1000.0) | |
| 605 | + self.log(" mCrab = ") | |
| 606 | + self.log(diffSens) | |
| 607 | + self.log(" erg/cm2/s\n") | |
| 608 | + | |
| 609 | + # Compute sliding average of extrapolated fitted prefactor, | |
| 610 | + # photon and energy flux. This damps out fluctuations and | |
| 611 | + # improves convergence | |
| 612 | + flux = 0.0 | |
| 613 | + pflux = 0.0 | |
| 614 | + eflux = 0.0 | |
| 615 | + diffSens = 0.0 | |
| 616 | + num = 0.0 | |
| 617 | + for k in range(self.m_num_avg): | |
| 618 | + inx = len(flux_value) - k - 1 | |
| 619 | + if inx >= 0: | |
| 620 | + flux += flux_value[inx] | |
| 621 | + pflux += pflux_value[inx] | |
| 622 | + eflux += eflux_value[inx] | |
| 623 | + diffSens += diffSens_value[inx] | |
| 624 | + num += 1.0 | |
| 625 | + flux /= num | |
| 626 | + pflux /= num | |
| 627 | + eflux /= num | |
| 628 | + diffSens /= num | |
| 629 | + | |
| 630 | + # Compare average flux to last average | |
| 631 | + if iter > self.m_num_avg: | |
| 632 | + if test_flux > 0: | |
| 633 | + ratio = flux/test_flux | |
| 634 | + | |
| 635 | + # We have 2 convergence criteria: | |
| 636 | + # 1. The average flux does not change | |
| 637 | + # 2. The flux correction factor is small | |
| 638 | + if ratio >= 0.99 and ratio <= 1.01 and \ | |
| 639 | + correct >= 0.9 and correct <= 1.1: | |
| 640 | + if self.logTerse(): | |
| 641 | + self.log(" Converged ("+str(ratio)+")\n") | |
| 642 | + break | |
| 643 | + else: | |
| 644 | + if self.logTerse(): | |
| 645 | + self.log(" Flux is zero.\n") | |
| 646 | + break | |
| 647 | + | |
| 648 | + # Use average for next iteration | |
| 649 | + test_flux = flux | |
| 650 | + | |
| 651 | + # Exit loop if number of trials exhausted | |
| 652 | + if (iter >= self.m_max_iter): | |
| 653 | + if self.logTerse(): | |
| 654 | + self.log(" Test ended after "+str(self.m_max_iter)+" iterations.\n") | |
| 655 | + break | |
| 656 | + | |
| 657 | + # Write fit results | |
| 658 | + if self.logTerse(): | |
| 659 | + self.log.header3("Fit results") | |
| 660 | + self.log.parformat("Test statistics") | |
| 661 | + self.log(ts) | |
| 662 | + self.log("\n") | |
| 663 | + self.log.parformat("Photon flux") | |
| 664 | + self.log(pflux) | |
| 665 | + self.log(" ph/cm2/s\n") | |
| 666 | + self.log.parformat("Energy flux") | |
| 667 | + self.log(eflux) | |
| 668 | + self.log(" erg/cm2/s\n") | |
| 669 | + self.log.parformat("Crab flux") | |
| 670 | + self.log(cflux*1000.0) | |
| 671 | + self.log(" mCrab\n") | |
| 672 | + self.log.parformat("Differential sensitivity") | |
| 673 | + self.log(diffSens) | |
| 674 | + self.log(" erg/cm2/s\n") | |
| 675 | + self.log.parformat("Number of simulated events") | |
| 676 | + self.log(nevents) | |
| 677 | + self.log("\n") | |
| 678 | + self.log.header3("Background and test source model fitting") | |
| 679 | + self.log.parformat("log likelihood") | |
| 680 | + self.log(LogL_all) | |
| 681 | + self.log("\n") | |
| 682 | + self.log.parformat("Number of predicted events") | |
| 683 | + self.log(npred_all) | |
| 684 | + self.log("\n") | |
| 685 | + for model in result_all: | |
| 686 | + self.log.parformat("Model") | |
| 687 | + self.log(model.name()) | |
| 688 | + self.log("\n") | |
| 689 | + for par in model: | |
| 690 | + self.log(str(par)+"\n") | |
| 691 | + self.log.header3("Background model fit") | |
| 692 | + self.log.parformat("log likelihood") | |
| 693 | + self.log(LogL_bgm) | |
| 694 | + self.log("\n") | |
| 695 | + self.log.parformat("Number of predicted events") | |
| 696 | + self.log(npred_bgm) | |
| 697 | + self.log("\n") | |
| 698 | + for model in result_bgm: | |
| 699 | + self.log.parformat("Model") | |
| 700 | + self.log(model.name()) | |
| 701 | + self.log("\n") | |
| 702 | + for par in model: | |
| 703 | + self.log(str(par)+"\n") | |
| 704 | + | |
| 705 | + # Store result | |
| 706 | + result = {'loge': loge, 'emin': emin.TeV(), 'emax': emax.TeV(), \ | |
| 707 | + 'crab': flux, 'pflux': pflux, 'eflux': eflux, \ | |
| 708 | + 'diffSens': diffSens} | |
| 709 | + | |
| 710 | + # Return result | |
| 711 | + return result | |
| 712 | 712 | |
| 713 | 713 | |
| 714 | 714 | # ======================== # |
| 715 | 715 | # Main routine entry point # |
| 716 | 716 | # ======================== # |
| 717 | 717 | if __name__ == '__main__': |
| 718 | - """ | |
| 719 | - CTA ctlike-based sensitivity estimator. | |
| 720 | - """ | |
| 721 | - # Create instance of application | |
| 722 | - app = cssens(sys.argv) | |
| 723 | - | |
| 724 | - # Run application | |
| 725 | - app.execute() | |
| 726 | - | |
| 727 | 718 | \ No newline at end of file |
| 719 | + """ | |
| 720 | + CTA ctlike-based sensitivity estimator. | |
| 721 | + """ | |
| 722 | + # Create instance of application | |
| 723 | + app = cssens(sys.argv) | |
| 724 | + | |
| 725 | + # Run application | |
| 726 | + app.execute() | |
| 727 | + | |
| 728 | 728 | \ No newline at end of file | ... | ... |
scripts/cstsdist.py
| ... | ... | @@ -3,7 +3,7 @@ |
| 3 | 3 | # This script generates the TS distribution for a particular model based |
| 4 | 4 | # on Monte-Carlo simulations. |
| 5 | 5 | # |
| 6 | -# Copyright (C) 2011-2013 Jurgen Knodlseder | |
| 6 | +# Copyright (C) 2011-2014 Juergen Knoedlseder | |
| 7 | 7 | # |
| 8 | 8 | # This program is free software: you can redistribute it and/or modify |
| 9 | 9 | # it under the terms of the GNU General Public License as published by |
| ... | ... | @@ -31,486 +31,486 @@ import math |
| 31 | 31 | # cstsdist class # |
| 32 | 32 | # ============== # |
| 33 | 33 | class cstsdist(GApplication): |
| 34 | - """ | |
| 35 | - This class implements the TS distribution generation script. It derives | |
| 36 | - from the GammaLib::GApplication class which provides support for parameter | |
| 37 | - files, command line arguments, and logging. In that way the Python | |
| 38 | - script behaves just as a regular ctool. | |
| 39 | - """ | |
| 40 | - def __init__(self, *argv): | |
| 41 | - """ | |
| 42 | - Constructor. | |
| 43 | - """ | |
| 44 | - # Set name | |
| 45 | - self.name = "cstsdist" | |
| 46 | - self.version = "0.1.0" | |
| 47 | - | |
| 48 | - # Initialise some members | |
| 49 | - self.obs = None | |
| 50 | - self.bkg_model = None | |
| 51 | - self.full_model = None | |
| 52 | - | |
| 53 | - # Make sure that parfile exists | |
| 54 | - file = self.parfile() | |
| 34 | + """ | |
| 35 | + This class implements the TS distribution generation script. It derives | |
| 36 | + from the GammaLib::GApplication class which provides support for parameter | |
| 37 | + files, command line arguments, and logging. In that way the Python | |
| 38 | + script behaves just as a regular ctool. | |
| 39 | + """ | |
| 40 | + def __init__(self, *argv): | |
| 41 | + """ | |
| 42 | + Constructor. | |
| 43 | + """ | |
| 44 | + # Set name | |
| 45 | + self.name = "cstsdist" | |
| 46 | + self.version = "0.1.0" | |
| 47 | + | |
| 48 | + # Initialise some members | |
| 49 | + self.obs = None | |
| 50 | + self.bkg_model = None | |
| 51 | + self.full_model = None | |
| 52 | + | |
| 53 | + # Make sure that parfile exists | |
| 54 | + file = self.parfile() | |
| 55 | 55 | |
| 56 | - # Initialise application | |
| 57 | - if len(argv) == 0: | |
| 58 | - GApplication.__init__(self, self.name, self.version) | |
| 59 | - elif len(argv) ==1: | |
| 60 | - GApplication.__init__(self, self.name, self.version, *argv) | |
| 61 | - else: | |
| 62 | - raise TypeError("Invalid number of arguments given.") | |
| 56 | + # Initialise application | |
| 57 | + if len(argv) == 0: | |
| 58 | + GApplication.__init__(self, self.name, self.version) | |
| 59 | + elif len(argv) ==1: | |
| 60 | + GApplication.__init__(self, self.name, self.version, *argv) | |
| 61 | + else: | |
| 62 | + raise TypeError("Invalid number of arguments given.") | |
| 63 | 63 | |
| 64 | - # Set logger properties | |
| 65 | - self.log_header() | |
| 66 | - self.log.date(True) | |
| 64 | + # Set logger properties | |
| 65 | + self.log_header() | |
| 66 | + self.log.date(True) | |
| 67 | 67 | |
| 68 | - # Return | |
| 69 | - return | |
| 70 | - | |
| 71 | - def __del__(self): | |
| 72 | - """ | |
| 73 | - Destructor. | |
| 74 | - """ | |
| 75 | - # Write separator into logger | |
| 76 | - if self.logTerse(): | |
| 77 | - self.log("\n") | |
| 78 | - | |
| 79 | - # Return | |
| 80 | - return | |
| 68 | + # Return | |
| 69 | + return | |
| 70 | + | |
| 71 | + def __del__(self): | |
| 72 | + """ | |
| 73 | + Destructor. | |
| 74 | + """ | |
| 75 | + # Write separator into logger | |
| 76 | + if self.logTerse(): | |
| 77 | + self.log("\n") | |
| 78 | + | |
| 79 | + # Return | |
| 80 | + return | |
| 81 | 81 | |
| 82 | - def parfile(self): | |
| 83 | - """ | |
| 84 | - Check if parfile exists. If parfile does not exist then create a | |
| 85 | - default parfile. This kluge avoids shipping the cscript with a parfile. | |
| 86 | - """ | |
| 87 | - # Set parfile name | |
| 88 | - parfile = self.name+".par" | |
| 89 | - | |
| 90 | - try: | |
| 91 | - pars = GApplicationPars(parfile) | |
| 92 | - except: | |
| 93 | - # Signal if parfile was not found | |
| 94 | - sys.stdout.write("Parfile "+parfile+" not found. Create default parfile.\n") | |
| 95 | - | |
| 96 | - # Create default parfile | |
| 97 | - pars = GApplicationPars() | |
| 98 | - pars.append(GApplicationPar("outfile","f","h","ts.dat","","","Output file name")) | |
| 99 | - pars.append(GApplicationPar("ntrials","i","a","10","","","Number of trials")) | |
| 100 | - pars.append(GApplicationPar("caldb","s","a","$GAMMALIB/share/caldb/cta","","","Calibration database")) | |
| 101 | - pars.append(GApplicationPar("irf","s","a","cta_dummy_irf","","","Instrument response function")) | |
| 102 | - pars.append(GApplicationPar("type","s","a","point","","","Source model type (point/gauss/shell/disk)")) | |
| 103 | - pars.append(GApplicationPar("index","r","h","-2.48","","","Spectral index")) | |
| 104 | - pars.append(GApplicationPar("offset","r","a","0.0","0.0","","Source offset angle (deg)")) | |
| 105 | - pars.append(GApplicationPar("bkg","s","a","$GAMMALIB/share/models/bkg_dummy.txt","","","Background model file function (none=power law for E)")) | |
| 106 | - pars.append(GApplicationPar("emin","r","a","0.1","0.0","","Lower energy limit (TeV)")) | |
| 107 | - pars.append(GApplicationPar("emax","r","a","100.0","0.0","","Upper energy limit (TeV)")) | |
| 108 | - pars.append(GApplicationPar("enumbins","i","a","0","","","Number of energy bins (0=unbinned)")) | |
| 109 | - pars.append(GApplicationPar("duration","r","a","180000.0","","","Effective exposure time (s)")) | |
| 110 | - pars.append(GApplicationPar("rad","r","h","5.0","","","Radius of ROI (deg)")) | |
| 111 | - pars.append(GApplicationPar("npix","i","h","200","","","Number of pixels for binned")) | |
| 112 | - pars.append(GApplicationPar("binsz","r","h","0.05","","","Pixel size for binned (deg/pixel)")) | |
| 113 | - pars.append_standard() | |
| 114 | - pars.save(parfile) | |
| 115 | - | |
| 116 | - # Return | |
| 117 | - return | |
| 118 | - | |
| 119 | - def get_parameters(self): | |
| 120 | - """ | |
| 121 | - Get parameters from parfile and setup the observation. | |
| 122 | - """ | |
| 123 | - # Get parameters | |
| 124 | - self.m_outfile = self["outfile"].filename() | |
| 125 | - self.m_ntrials = self["ntrials"].integer() | |
| 126 | - self.m_caldb = self["caldb"].string() | |
| 127 | - self.m_irf = self["irf"].string() | |
| 128 | - self.m_type = self["type"].string() | |
| 129 | - self.m_index = self["index"].real() | |
| 130 | - self.m_offset = self["offset"].real() | |
| 131 | - self.m_bkg = self["bkg"].string() | |
| 132 | - self.m_emin = self["emin"].real() | |
| 133 | - self.m_emax = self["emax"].real() | |
| 134 | - self.m_enumbins = self["enumbins"].integer() | |
| 135 | - self.m_duration = self["duration"].real() | |
| 136 | - self.m_rad = self["rad"].real() | |
| 137 | - self.m_npix = self["npix"].integer() | |
| 138 | - self.m_binsz = self["binsz"].real() | |
| 82 | + def parfile(self): | |
| 83 | + """ | |
| 84 | + Check if parfile exists. If parfile does not exist then create a | |
| 85 | + default parfile. This kluge avoids shipping the cscript with a parfile. | |
| 86 | + """ | |
| 87 | + # Set parfile name | |
| 88 | + parfile = self.name+".par" | |
| 89 | + | |
| 90 | + try: | |
| 91 | + pars = GApplicationPars(parfile) | |
| 92 | + except: | |
| 93 | + # Signal if parfile was not found | |
| 94 | + sys.stdout.write("Parfile "+parfile+" not found. Create default parfile.\n") | |
| 95 | + | |
| 96 | + # Create default parfile | |
| 97 | + pars = GApplicationPars() | |
| 98 | + pars.append(GApplicationPar("outfile","f","h","ts.dat","","","Output file name")) | |
| 99 | + pars.append(GApplicationPar("ntrials","i","a","10","","","Number of trials")) | |
| 100 | + pars.append(GApplicationPar("caldb","s","a","$GAMMALIB/share/caldb/cta","","","Calibration database")) | |
| 101 | + pars.append(GApplicationPar("irf","s","a","cta_dummy_irf","","","Instrument response function")) | |
| 102 | + pars.append(GApplicationPar("type","s","a","point","","","Source model type (point/gauss/shell/disk)")) | |
| 103 | + pars.append(GApplicationPar("index","r","h","-2.48","","","Spectral index")) | |
| 104 | + pars.append(GApplicationPar("offset","r","a","0.0","0.0","","Source offset angle (deg)")) | |
| 105 | + pars.append(GApplicationPar("bkg","s","a","$GAMMALIB/share/models/bkg_dummy.txt","","","Background model file function (none=power law for E)")) | |
| 106 | + pars.append(GApplicationPar("emin","r","a","0.1","0.0","","Lower energy limit (TeV)")) | |
| 107 | + pars.append(GApplicationPar("emax","r","a","100.0","0.0","","Upper energy limit (TeV)")) | |
| 108 | + pars.append(GApplicationPar("enumbins","i","a","0","","","Number of energy bins (0=unbinned)")) | |
| 109 | + pars.append(GApplicationPar("duration","r","a","180000.0","","","Effective exposure time (s)")) | |
| 110 | + pars.append(GApplicationPar("rad","r","h","5.0","","","Radius of ROI (deg)")) | |
| 111 | + pars.append(GApplicationPar("npix","i","h","200","","","Number of pixels for binned")) | |
| 112 | + pars.append(GApplicationPar("binsz","r","h","0.05","","","Pixel size for binned (deg/pixel)")) | |
| 113 | + pars.append_standard() | |
| 114 | + pars.save(parfile) | |
| 115 | + | |
| 116 | + # Return | |
| 117 | + return | |
| 118 | + | |
| 119 | + def get_parameters(self): | |
| 120 | + """ | |
| 121 | + Get parameters from parfile and setup the observation. | |
| 122 | + """ | |
| 123 | + # Get parameters | |
| 124 | + self.m_outfile = self["outfile"].filename() | |
| 125 | + self.m_ntrials = self["ntrials"].integer() | |
| 126 | + self.m_caldb = self["caldb"].string() | |
| 127 | + self.m_irf = self["irf"].string() | |
| 128 | + self.m_type = self["type"].string() | |
| 129 | + self.m_index = self["index"].real() | |
| 130 | + self.m_offset = self["offset"].real() | |
| 131 | + self.m_bkg = self["bkg"].string() | |
| 132 | + self.m_emin = self["emin"].real() | |
| 133 | + self.m_emax = self["emax"].real() | |
| 134 | + self.m_enumbins = self["enumbins"].integer() | |
| 135 | + self.m_duration = self["duration"].real() | |
| 136 | + self.m_rad = self["rad"].real() | |
| 137 | + self.m_npix = self["npix"].integer() | |
| 138 | + self.m_binsz = self["binsz"].real() | |
| 139 | 139 | |
| 140 | - # Set some fixed parameters | |
| 141 | - self.m_log = False # Logging in client tools | |
| 142 | - self.m_debug = False # Debugging in client tools | |
| 143 | - | |
| 144 | - # Setup observation | |
| 145 | - self.obs = self.set_obs(emin=self.m_emin, emax=self.m_emax) | |
| 146 | - | |
| 147 | - # Initialise models. Note that we centre the point source at the Galactic | |
| 148 | - # center as our observation is also centred at the Galactic centre, so | |
| 149 | - # we're onaxis. | |
| 150 | - self.bkg_model = GModels() | |
| 151 | - self.full_model = GModels() | |
| 152 | - self.bkg_model.append(self.set_bkg_model()) | |
| 153 | - self.full_model.append(self.set_bkg_model()) | |
| 154 | - self.full_model.append(self.set_src_model(0.0, self.m_offset, \ | |
| 155 | - flux=0.010, \ | |
| 156 | - type=self.m_type, \ | |
| 157 | - index=self.m_index)) | |
| 140 | + # Set some fixed parameters | |
| 141 | + self.m_log = False # Logging in client tools | |
| 142 | + self.m_debug = False # Debugging in client tools | |
| 143 | + | |
| 144 | + # Setup observation | |
| 145 | + self.obs = self.set_obs(emin=self.m_emin, emax=self.m_emax) | |
| 146 | + | |
| 147 | + # Initialise models. Note that we centre the point source at the Galactic | |
| 148 | + # center as our observation is also centred at the Galactic centre, so | |
| 149 | + # we're onaxis. | |
| 150 | + self.bkg_model = GModels() | |
| 151 | + self.full_model = GModels() | |
| 152 | + self.bkg_model.append(self.set_bkg_model()) | |
| 153 | + self.full_model.append(self.set_bkg_model()) | |
| 154 | + self.full_model.append(self.set_src_model(0.0, self.m_offset, \ | |
| 155 | + flux=0.010, \ | |
| 156 | + type=self.m_type, \ | |
| 157 | + index=self.m_index)) | |
| 158 | 158 | |
| 159 | - # Attach background model to observation container | |
| 160 | - self.obs.models(self.bkg_model) | |
| 161 | - | |
| 162 | - # Return | |
| 163 | - return | |
| 164 | - | |
| 165 | - def models(self, models): | |
| 166 | - """ | |
| 167 | - Set model. | |
| 168 | - """ | |
| 169 | - # Copy models | |
| 170 | - self.model = models.copy() | |
| 171 | - | |
| 172 | - # Return | |
| 173 | - return | |
| 174 | - | |
| 175 | - def execute(self): | |
| 176 | - """ | |
| 177 | - Execute the script. | |
| 178 | - """ | |
| 179 | - # Run the script | |
| 180 | - self.run() | |
| 181 | - | |
| 182 | - # Return | |
| 183 | - return | |
| 159 | + # Attach background model to observation container | |
| 160 | + self.obs.models(self.bkg_model) | |
| 161 | + | |
| 162 | + # Return | |
| 163 | + return | |
| 164 | + | |
| 165 | + def models(self, models): | |
| 166 | + """ | |
| 167 | + Set model. | |
| 168 | + """ | |
| 169 | + # Copy models | |
| 170 | + self.model = models.copy() | |
| 171 | + | |
| 172 | + # Return | |
| 173 | + return | |
| 174 | + | |
| 175 | + def execute(self): | |
| 176 | + """ | |
| 177 | + Execute the script. | |
| 178 | + """ | |
| 179 | + # Run the script | |
| 180 | + self.run() | |
| 181 | + | |
| 182 | + # Return | |
| 183 | + return | |
| 184 | 184 | |
| 185 | - def run(self): | |
| 186 | - """ | |
| 187 | - Run the script. | |
| 188 | - """ | |
| 189 | - # Switch screen logging on in debug mode | |
| 190 | - if self.logDebug(): | |
| 191 | - self.log.cout(True) | |
| 185 | + def run(self): | |
| 186 | + """ | |
| 187 | + Run the script. | |
| 188 | + """ | |
| 189 | + # Switch screen logging on in debug mode | |
| 190 | + if self.logDebug(): | |
| 191 | + self.log.cout(True) | |
| 192 | 192 | |
| 193 | - # Get parameters | |
| 194 | - self.get_parameters() | |
| 195 | - | |
| 196 | - # Write input parameters into logger | |
| 197 | - if self.logTerse(): | |
| 198 | - self.log_parameters() | |
| 199 | - self.log("\n") | |
| 200 | - | |
| 201 | - # Write observation into logger | |
| 202 | - if self.logTerse(): | |
| 203 | - self.log("\n") | |
| 204 | - self.log.header1("Observation") | |
| 205 | - self.log(str(self.obs)) | |
| 206 | - self.log("\n") | |
| 193 | + # Get parameters | |
| 194 | + self.get_parameters() | |
| 195 | + | |
| 196 | + # Write input parameters into logger | |
| 197 | + if self.logTerse(): | |
| 198 | + self.log_parameters() | |
| 199 | + self.log("\n") | |
| 200 | + | |
| 201 | + # Write observation into logger | |
| 202 | + if self.logTerse(): | |
| 203 | + self.log("\n") | |
| 204 | + self.log.header1("Observation") | |
| 205 | + self.log(str(self.obs)) | |
| 206 | + self.log("\n") | |
| 207 | 207 | |
| 208 | - # Write models into logger | |
| 209 | - if self.logTerse(): | |
| 210 | - self.log("\n") | |
| 211 | - self.log.header1("Test model") | |
| 212 | - self.log(str(self.full_model)) | |
| 213 | - self.log("\n") | |
| 208 | + # Write models into logger | |
| 209 | + if self.logTerse(): | |
| 210 | + self.log("\n") | |
| 211 | + self.log.header1("Test model") | |
| 212 | + self.log(str(self.full_model)) | |
| 213 | + self.log("\n") | |
| 214 | 214 | |
| 215 | - # Write header | |
| 216 | - if self.logTerse(): | |
| 217 | - self.log("\n") | |
| 218 | - self.log.header1("Generate TS distribution") | |
| 215 | + # Write header | |
| 216 | + if self.logTerse(): | |
| 217 | + self.log("\n") | |
| 218 | + self.log.header1("Generate TS distribution") | |
| 219 | 219 | |
| 220 | - # Loop over trials | |
| 221 | - for seed in range(self.m_ntrials): | |
| 222 | - | |
| 223 | - # Make a trial | |
| 224 | - result = self.trial(seed) | |
| 225 | - | |
| 226 | - # Write out result immediately | |
| 227 | - if seed == 0: | |
| 228 | - file = open(self.m_outfile, 'w') | |
| 229 | - writer = csv.DictWriter(file, result['colnames']) | |
| 230 | - writer.writerow(dict((_,_) for _ in result['colnames'])) | |
| 231 | - else: | |
| 232 | - file = open(self.m_outfile, 'a') | |
| 233 | - writer = csv.DictWriter(file, result['colnames']) | |
| 234 | - writer.writerow(result['values']) | |
| 235 | - file.close() | |
| 236 | - | |
| 237 | - # Return | |
| 238 | - return | |
| 239 | - | |
| 240 | - def set_obs(self, lpnt=0.0, bpnt=0.0, emin=0.1, emax=100.0): | |
| 241 | - """ | |
| 242 | - Returns an observation container with a single CTA observation. | |
| 243 | - | |
| 244 | - Keywords: | |
| 245 | - lpnt - Galactic longitude of pointing [deg] (default: 0.0) | |
| 246 | - bpnt - Galactic latitude of pointing [deg] (default: 0.0) | |
| 247 | - emin - Minimum energy [TeV] (default: 0.1) | |
| 248 | - emax - Maximum energy [TeV] (default: 100.0) | |
| 249 | - """ | |
| 250 | - # Allocate observation container | |
| 251 | - obs = GObservations() | |
| 252 | - | |
| 253 | - # Set single pointing | |
| 254 | - pntdir = GSkyDir() | |
| 255 | - pntdir.lb_deg(lpnt, bpnt) | |
| 256 | - | |
| 257 | - # Create CTA observation | |
| 258 | - run = obsutils.set(pntdir, caldb=self.m_caldb, irf=self.m_irf, \ | |
| 259 | - duration=self.m_duration, \ | |
| 220 | + # Loop over trials | |
| 221 | + for seed in range(self.m_ntrials): | |
| 222 | + | |
| 223 | + # Make a trial | |
| 224 | + result = self.trial(seed) | |
| 225 | + | |
| 226 | + # Write out result immediately | |
| 227 | + if seed == 0: | |
| 228 | + file = open(self.m_outfile, 'w') | |
| 229 | + writer = csv.DictWriter(file, result['colnames']) | |
| 230 | + writer.writerow(dict((_,_) for _ in result['colnames'])) | |
| 231 | + else: | |
| 232 | + file = open(self.m_outfile, 'a') | |
| 233 | + writer = csv.DictWriter(file, result['colnames']) | |
| 234 | + writer.writerow(result['values']) | |
| 235 | + file.close() | |
| 236 | + | |
| 237 | + # Return | |
| 238 | + return | |
| 239 | + | |
| 240 | + def set_obs(self, lpnt=0.0, bpnt=0.0, emin=0.1, emax=100.0): | |
| 241 | + """ | |
| 242 | + Returns an observation container with a single CTA observation. | |
| 243 | + | |
| 244 | + Keywords: | |
| 245 | + lpnt - Galactic longitude of pointing [deg] (default: 0.0) | |
| 246 | + bpnt - Galactic latitude of pointing [deg] (default: 0.0) | |
| 247 | + emin - Minimum energy [TeV] (default: 0.1) | |
| 248 | + emax - Maximum energy [TeV] (default: 100.0) | |
| 249 | + """ | |
| 250 | + # Allocate observation container | |
| 251 | + obs = GObservations() | |
| 252 | + | |
| 253 | + # Set single pointing | |
| 254 | + pntdir = GSkyDir() | |
| 255 | + pntdir.lb_deg(lpnt, bpnt) | |
| 256 | + | |
| 257 | + # Create CTA observation | |
| 258 | + run = obsutils.set(pntdir, caldb=self.m_caldb, irf=self.m_irf, \ | |
| 259 | + duration=self.m_duration, \ | |
| 260 | 260 | emin=emin, emax=emax, rad=self.m_rad) |
| 261 | - | |
| 262 | - # Append observation to container | |
| 263 | - obs.append(run) | |
| 264 | - | |
| 265 | - # Return observation container | |
| 266 | - return obs | |
| 267 | - | |
| 268 | - def set_bkg_model(self, fitsigma=False): | |
| 269 | - """ | |
| 270 | - Setup CTA background model. | |
| 271 | - """ | |
| 272 | - # Define radial component | |
| 273 | - radial = GCTAModelRadialGauss(3.0) | |
| 274 | - if fitsigma: | |
| 275 | - radial["Sigma"].free() | |
| 276 | - else: | |
| 277 | - radial["Sigma"].fix() | |
| 278 | - | |
| 279 | - # Define spectral component | |
| 280 | - spectrum = GModelSpectralFunc(self.m_bkg, 1.0) | |
| 281 | - | |
| 282 | - # Create background model | |
| 283 | - model = GCTAModelRadialAcceptance(radial, spectrum) | |
| 284 | - model.name("Background") | |
| 285 | - model.instruments("CTA") | |
| 286 | - | |
| 287 | - # Return background model | |
| 288 | - return model | |
| 289 | - | |
| 290 | - def set_src_model(self, l, b, flux=1.0, index=-2.48, \ | |
| 261 | + | |
| 262 | + # Append observation to container | |
| 263 | + obs.append(run) | |
| 264 | + | |
| 265 | + # Return observation container | |
| 266 | + return obs | |
| 267 | + | |
| 268 | + def set_bkg_model(self, fitsigma=False): | |
| 269 | + """ | |
| 270 | + Setup CTA background model. | |
| 271 | + """ | |
| 272 | + # Define radial component | |
| 273 | + radial = GCTAModelRadialGauss(3.0) | |
| 274 | + if fitsigma: | |
| 275 | + radial["Sigma"].free() | |
| 276 | + else: | |
| 277 | + radial["Sigma"].fix() | |
| 278 | + | |
| 279 | + # Define spectral component | |
| 280 | + spectrum = GModelSpectralFunc(self.m_bkg, 1.0) | |
| 281 | + | |
| 282 | + # Create background model | |
| 283 | + model = GCTAModelRadialAcceptance(radial, spectrum) | |
| 284 | + model.name("Background") | |
| 285 | + model.instruments("CTA") | |
| 286 | + | |
| 287 | + # Return background model | |
| 288 | + return model | |
| 289 | + | |
| 290 | + def set_src_model(self, l, b, flux=1.0, index=-2.48, \ | |
| 291 | 291 | type="point", sigma=1.0, radius=1.0, width=0.1, \ |
| 292 | 292 | fitpos=False, fitidx=False): |
| 293 | - """ | |
| 294 | - Returns a single source with Crab-like spectrum. The source flux | |
| 295 | - can be scaled in Crab units. The Crab spectrum is based on MAGIC | |
| 296 | - observations (Albert et al. 2008, ApJ, 674, 1037). | |
| 293 | + """ | |
| 294 | + Returns a single source with Crab-like spectrum. The source flux | |
| 295 | + can be scaled in Crab units. The Crab spectrum is based on MAGIC | |
| 296 | + observations (Albert et al. 2008, ApJ, 674, 1037). | |
| 297 | 297 | |
| 298 | - Parameters: | |
| 299 | - l - Galactic longitude of source location [deg] | |
| 300 | - b - Galactic latitude of source location [deg] | |
| 301 | - Keywords: | |
| 302 | - flux - Source flux [Crabs] | |
| 303 | - index - Spectral index | |
| 304 | - type - Source type ("point", "gauss", "disk", "shell") | |
| 305 | - sigma - Gaussian sigma (for type="gauss") | |
| 306 | - radius - Disk or shell inner radius [deg] (for type="disk" and type="shell") | |
| 307 | - width - Shell width [deg] (for type="shell") | |
| 308 | - fitpos - Fit position? (default: True) | |
| 309 | - fitidx - Fit index? (default: True) | |
| 310 | - """ | |
| 311 | - # Set source location | |
| 312 | - location = GSkyDir() | |
| 313 | - location.lb_deg(l, b) | |
| 314 | - | |
| 315 | - # Set source spectrum | |
| 316 | - spectrum = GModelSpectralPlaw(flux*5.7e-16, index, GEnergy(0.3, "TeV")) | |
| 317 | - if fitidx: | |
| 318 | - spectrum["Index"].free() | |
| 319 | - else: | |
| 320 | - spectrum["Index"].fix() | |
| 298 | + Parameters: | |
| 299 | + l - Galactic longitude of source location [deg] | |
| 300 | + b - Galactic latitude of source location [deg] | |
| 301 | + Keywords: | |
| 302 | + flux - Source flux [Crabs] | |
| 303 | + index - Spectral index | |
| 304 | + type - Source type ("point", "gauss", "disk", "shell") | |
| 305 | + sigma - Gaussian sigma (for type="gauss") | |
| 306 | + radius - Disk or shell inner radius [deg] (for type="disk" and type="shell") | |
| 307 | + width - Shell width [deg] (for type="shell") | |
| 308 | + fitpos - Fit position? (default: True) | |
| 309 | + fitidx - Fit index? (default: True) | |
| 310 | + """ | |
| 311 | + # Set source location | |
| 312 | + location = GSkyDir() | |
| 313 | + location.lb_deg(l, b) | |
| 314 | + | |
| 315 | + # Set source spectrum | |
| 316 | + spectrum = GModelSpectralPlaw(flux*5.7e-16, index, GEnergy(0.3, "TeV")) | |
| 317 | + if fitidx: | |
| 318 | + spectrum["Index"].free() | |
| 319 | + else: | |
| 320 | + spectrum["Index"].fix() | |
| 321 | 321 | |
| 322 | - # Set source | |
| 323 | - if type == "point": | |
| 324 | - spatial = GModelSpatialPointSource(location) | |
| 325 | - if fitpos: | |
| 326 | - spatial[0].free() | |
| 327 | - spatial[1].free() | |
| 328 | - elif type == "gauss": | |
| 329 | - spatial = GModelSpatialRadialGauss(location, sigma) | |
| 330 | - if fitpos: | |
| 331 | - spatial[0].free() | |
| 332 | - spatial[1].free() | |
| 333 | - elif type == "disk": | |
| 334 | - spatial = GModelSpatialRadialDisk(location, radius) | |
| 335 | - if fitpos: | |
| 336 | - spatial[0].free() | |
| 337 | - spatial[1].free() | |
| 338 | - elif type == "shell": | |
| 339 | - spatial = GModelSpatialRadialShell(location, radius, width) | |
| 340 | - if fitpos: | |
| 341 | - spatial[0].free() | |
| 342 | - spatial[1].free() | |
| 343 | - else: | |
| 344 | - self.log("ERROR: Unknown source type '"+type+"'.\n") | |
| 345 | - return None | |
| 346 | - source = GModelSky(spatial, spectrum) | |
| 347 | - | |
| 348 | - # Set source name | |
| 349 | - source.name("Test") | |
| 350 | - | |
| 351 | - # Return source | |
| 352 | - return source | |
| 353 | - | |
| 354 | - def trial(self, seed): | |
| 355 | - """ | |
| 356 | - Create the TS for a single trial. | |
| 357 | - | |
| 358 | - Parameters: | |
| 359 | - seed - Random number generator seed | |
| 360 | - """ | |
| 361 | - # Write header | |
| 362 | - if self.logExplicit(): | |
| 363 | - self.log.header2("Trial "+str(seed+1)) | |
| 322 | + # Set source | |
| 323 | + if type == "point": | |
| 324 | + spatial = GModelSpatialPointSource(location) | |
| 325 | + if fitpos: | |
| 326 | + spatial[0].free() | |
| 327 | + spatial[1].free() | |
| 328 | + elif type == "gauss": | |
| 329 | + spatial = GModelSpatialRadialGauss(location, sigma) | |
| 330 | + if fitpos: | |
| 331 | + spatial[0].free() | |
| 332 | + spatial[1].free() | |
| 333 | + elif type == "disk": | |
| 334 | + spatial = GModelSpatialRadialDisk(location, radius) | |
| 335 | + if fitpos: | |
| 336 | + spatial[0].free() | |
| 337 | + spatial[1].free() | |
| 338 | + elif type == "shell": | |
| 339 | + spatial = GModelSpatialRadialShell(location, radius, width) | |
| 340 | + if fitpos: | |
| 341 | + spatial[0].free() | |
| 342 | + spatial[1].free() | |
| 343 | + else: | |
| 344 | + self.log("ERROR: Unknown source type '"+type+"'.\n") | |
| 345 | + return None | |
| 346 | + source = GModelSky(spatial, spectrum) | |
| 347 | + | |
| 348 | + # Set source name | |
| 349 | + source.name("Test") | |
| 350 | + | |
| 351 | + # Return source | |
| 352 | + return source | |
| 353 | + | |
| 354 | + def trial(self, seed): | |
| 355 | + """ | |
| 356 | + Create the TS for a single trial. | |
| 357 | + | |
| 358 | + Parameters: | |
| 359 | + seed - Random number generator seed | |
| 360 | + """ | |
| 361 | + # Write header | |
| 362 | + if self.logExplicit(): | |
| 363 | + self.log.header2("Trial "+str(seed+1)) | |
| 364 | 364 | |
| 365 | - # Simulate events | |
| 366 | - sim = obsutils.sim(self.obs, \ | |
| 367 | - nbins=self.m_enumbins, \ | |
| 368 | - seed=seed, \ | |
| 369 | - binsz=self.m_binsz, \ | |
| 370 | - npix=self.m_npix, \ | |
| 371 | - log=self.m_log, debug=self.m_debug) | |
| 365 | + # Simulate events | |
| 366 | + sim = obsutils.sim(self.obs, \ | |
| 367 | + nbins=self.m_enumbins, \ | |
| 368 | + seed=seed, \ | |
| 369 | + binsz=self.m_binsz, \ | |
| 370 | + npix=self.m_npix, \ | |
| 371 | + log=self.m_log, debug=self.m_debug) | |
| 372 | 372 | |
| 373 | - # Determine number of events in simulation | |
| 374 | - nevents = 0.0 | |
| 375 | - for run in sim: | |
| 376 | - nevents += run.events().number() | |
| 373 | + # Determine number of events in simulation | |
| 374 | + nevents = 0.0 | |
| 375 | + for run in sim: | |
| 376 | + nevents += run.events().number() | |
| 377 | 377 | |
| 378 | - # Write simulation results | |
| 379 | - if self.logExplicit(): | |
| 380 | - self.log.header3("Simulation") | |
| 381 | - self.log.parformat("Number of simulated events") | |
| 382 | - self.log(nevents) | |
| 383 | - self.log("\n") | |
| 378 | + # Write simulation results | |
| 379 | + if self.logExplicit(): | |
| 380 | + self.log.header3("Simulation") | |
| 381 | + self.log.parformat("Number of simulated events") | |
| 382 | + self.log(nevents) | |
| 383 | + self.log("\n") | |
| 384 | 384 | |
| 385 | - # Fit background only | |
| 386 | - sim.models(self.bkg_model) | |
| 387 | - like_bgm = obsutils.fit(sim, log=self.m_log, debug=self.m_debug) | |
| 388 | - result_bgm = like_bgm.obs().models() | |
| 389 | - LogL_bgm = like_bgm.opt().value() | |
| 390 | - npred_bgm = like_bgm.obs().npred() | |
| 385 | + # Fit background only | |
| 386 | + sim.models(self.bkg_model) | |
| 387 | + like_bgm = obsutils.fit(sim, log=self.m_log, debug=self.m_debug) | |
| 388 | + result_bgm = like_bgm.obs().models() | |
| 389 | + LogL_bgm = like_bgm.opt().value() | |
| 390 | + npred_bgm = like_bgm.obs().npred() | |
| 391 | 391 | |
| 392 | - # Write background fit results | |
| 393 | - if self.logExplicit(): | |
| 394 | - self.log.header3("Background model fit") | |
| 395 | - self.log.parformat("log likelihood") | |
| 396 | - self.log(LogL_bgm) | |
| 397 | - self.log("\n") | |
| 398 | - self.log.parformat("Number of predicted events") | |
| 399 | - self.log(npred_bgm) | |
| 400 | - self.log("\n") | |
| 401 | - for model in result_bgm: | |
| 402 | - self.log.parformat("Model") | |
| 403 | - self.log(model.name()) | |
| 404 | - self.log("\n") | |
| 405 | - for par in model: | |
| 406 | - self.log(str(par)+"\n") | |
| 392 | + # Write background fit results | |
| 393 | + if self.logExplicit(): | |
| 394 | + self.log.header3("Background model fit") | |
| 395 | + self.log.parformat("log likelihood") | |
| 396 | + self.log(LogL_bgm) | |
| 397 | + self.log("\n") | |
| 398 | + self.log.parformat("Number of predicted events") | |
| 399 | + self.log(npred_bgm) | |
| 400 | + self.log("\n") | |
| 401 | + for model in result_bgm: | |
| 402 | + self.log.parformat("Model") | |
| 403 | + self.log(model.name()) | |
| 404 | + self.log("\n") | |
| 405 | + for par in model: | |
| 406 | + self.log(str(par)+"\n") | |
| 407 | 407 | |
| 408 | - # Fit background and test source | |
| 409 | - sim.models(self.full_model) | |
| 410 | - like_all = obsutils.fit(sim, log=self.m_log, debug=self.m_debug) | |
| 411 | - result_all = like_all.obs().models() | |
| 412 | - LogL_all = like_all.opt().value() | |
| 413 | - npred_all = like_all.obs().npred() | |
| 414 | - ts = 2.0*(LogL_bgm-LogL_all) | |
| 415 | - | |
| 416 | - # Write background and test source fit results | |
| 417 | - if self.logExplicit(): | |
| 418 | - self.log.header3("Background and test source model fit") | |
| 419 | - self.log.parformat("Test statistics") | |
| 420 | - self.log(ts) | |
| 421 | - self.log("\n") | |
| 422 | - self.log.parformat("log likelihood") | |
| 423 | - self.log(LogL_all) | |
| 424 | - self.log("\n") | |
| 425 | - self.log.parformat("Number of predicted events") | |
| 426 | - self.log(npred_all) | |
| 427 | - self.log("\n") | |
| 428 | - for model in result_all: | |
| 429 | - self.log.parformat("Model") | |
| 430 | - self.log(model.name()) | |
| 431 | - self.log("\n") | |
| 432 | - for par in model: | |
| 433 | - self.log(str(par)+"\n") | |
| 434 | - | |
| 435 | - # Write result | |
| 436 | - elif self.logTerse(): | |
| 437 | - self.log.parformat("Trial "+str(seed)) | |
| 438 | - self.log("TS=") | |
| 439 | - self.log(ts) | |
| 440 | - self.log(" Prefactor=") | |
| 441 | - self.log(result_all["Test"]["Prefactor"].value()) | |
| 442 | - self.log("+/-") | |
| 443 | - self.log(result_all["Test"]["Prefactor"].error()) | |
| 444 | - self.log("\n") | |
| 445 | - | |
| 446 | - # Initialise results | |
| 447 | - colnames = [] | |
| 448 | - values = {} | |
| 449 | - | |
| 450 | - # Set TS value | |
| 451 | - colnames.append("TS") | |
| 452 | - values["TS"] = ts | |
| 408 | + # Fit background and test source | |
| 409 | + sim.models(self.full_model) | |
| 410 | + like_all = obsutils.fit(sim, log=self.m_log, debug=self.m_debug) | |
| 411 | + result_all = like_all.obs().models() | |
| 412 | + LogL_all = like_all.opt().value() | |
| 413 | + npred_all = like_all.obs().npred() | |
| 414 | + ts = 2.0*(LogL_bgm-LogL_all) | |
| 415 | + | |
| 416 | + # Write background and test source fit results | |
| 417 | + if self.logExplicit(): | |
| 418 | + self.log.header3("Background and test source model fit") | |
| 419 | + self.log.parformat("Test statistics") | |
| 420 | + self.log(ts) | |
| 421 | + self.log("\n") | |
| 422 | + self.log.parformat("log likelihood") | |
| 423 | + self.log(LogL_all) | |
| 424 | + self.log("\n") | |
| 425 | + self.log.parformat("Number of predicted events") | |
| 426 | + self.log(npred_all) | |
| 427 | + self.log("\n") | |
| 428 | + for model in result_all: | |
| 429 | + self.log.parformat("Model") | |
| 430 | + self.log(model.name()) | |
| 431 | + self.log("\n") | |
| 432 | + for par in model: | |
| 433 | + self.log(str(par)+"\n") | |
| 434 | + | |
| 435 | + # Write result | |
| 436 | + elif self.logTerse(): | |
| 437 | + self.log.parformat("Trial "+str(seed)) | |
| 438 | + self.log("TS=") | |
| 439 | + self.log(ts) | |
| 440 | + self.log(" Prefactor=") | |
| 441 | + self.log(result_all["Test"]["Prefactor"].value()) | |
| 442 | + self.log("+/-") | |
| 443 | + self.log(result_all["Test"]["Prefactor"].error()) | |
| 444 | + self.log("\n") | |
| 445 | + | |
| 446 | + # Initialise results | |
| 447 | + colnames = [] | |
| 448 | + values = {} | |
| 449 | + | |
| 450 | + # Set TS value | |
| 451 | + colnames.append("TS") | |
| 452 | + values["TS"] = ts | |
| 453 | 453 | |
| 454 | - # Set logL for background fit | |
| 455 | - colnames.append("LogL_bgm") | |
| 456 | - values["LogL_bgm"] = LogL_bgm | |
| 454 | + # Set logL for background fit | |
| 455 | + colnames.append("LogL_bgm") | |
| 456 | + values["LogL_bgm"] = LogL_bgm | |
| 457 | 457 | |
| 458 | - # Set logL for full fit | |
| 459 | - colnames.append("LogL_all") | |
| 460 | - values["LogL_all"] = LogL_all | |
| 458 | + # Set logL for full fit | |
| 459 | + colnames.append("LogL_all") | |
| 460 | + values["LogL_all"] = LogL_all | |
| 461 | 461 | |
| 462 | - # Set Nevents | |
| 463 | - colnames.append("Nevents") | |
| 464 | - values["Nevents"] = nevents | |
| 462 | + # Set Nevents | |
| 463 | + colnames.append("Nevents") | |
| 464 | + values["Nevents"] = nevents | |
| 465 | 465 | |
| 466 | - # Set Npred for background fit | |
| 467 | - colnames.append("Npred_bkg") | |
| 468 | - values["Npred_bkg"] = npred_bgm | |
| 466 | + # Set Npred for background fit | |
| 467 | + colnames.append("Npred_bkg") | |
| 468 | + values["Npred_bkg"] = npred_bgm | |
| 469 | 469 | |
| 470 | - # Set Npred for full fit | |
| 471 | - colnames.append("Npred_all") | |
| 472 | - values["Npred_all"] = npred_all | |
| 473 | - | |
| 474 | - # Gather free full fit parameters | |
| 475 | - for i in range(result_all.size()): | |
| 476 | - model = result_all[i] | |
| 477 | - model_name = model.name() | |
| 478 | - for k in range(model.size()): | |
| 479 | - par = model[k] | |
| 480 | - if par.is_free(): | |
| 481 | - | |
| 482 | - # Set parameter name | |
| 483 | - name = model_name+"_"+par.name() | |
| 484 | - | |
| 485 | - # Append value | |
| 486 | - colnames.append(name) | |
| 487 | - values[name] = par.value() | |
| 488 | - | |
| 489 | - # Append error | |
| 490 | - name = "Unc_"+name | |
| 491 | - colnames.append(name) | |
| 492 | - values[name] = par.error() | |
| 493 | - | |
| 494 | - # Bundle together results | |
| 495 | - result = {'colnames': colnames, 'values': values} | |
| 496 | - | |
| 497 | - # Return | |
| 498 | - return result | |
| 470 | + # Set Npred for full fit | |
| 471 | + colnames.append("Npred_all") | |
| 472 | + values["Npred_all"] = npred_all | |
| 473 | + | |
| 474 | + # Gather free full fit parameters | |
| 475 | + for i in range(result_all.size()): | |
| 476 | + model = result_all[i] | |
| 477 | + model_name = model.name() | |
| 478 | + for k in range(model.size()): | |
| 479 | + par = model[k] | |
| 480 | + if par.is_free(): | |
| 481 | + | |
| 482 | + # Set parameter name | |
| 483 | + name = model_name+"_"+par.name() | |
| 484 | + | |
| 485 | + # Append value | |
| 486 | + colnames.append(name) | |
| 487 | + values[name] = par.value() | |
| 488 | + | |
| 489 | + # Append error | |
| 490 | + name = "Unc_"+name | |
| 491 | + colnames.append(name) | |
| 492 | + values[name] = par.error() | |
| 493 | + | |
| 494 | + # Bundle together results | |
| 495 | + result = {'colnames': colnames, 'values': values} | |
| 496 | + | |
| 497 | + # Return | |
| 498 | + return result | |
| 499 | 499 | |
| 500 | 500 | |
| 501 | 501 | # ======================== # |
| 502 | 502 | # Main routine entry point # |
| 503 | 503 | # ======================== # |
| 504 | 504 | if __name__ == '__main__': |
| 505 | - """ | |
| 506 | - Generates TS distribution. | |
| 507 | - """ | |
| 508 | - # Create instance of application | |
| 509 | - app = cstsdist(sys.argv) | |
| 510 | - | |
| 511 | - # Open logfile | |
| 512 | - app.logFileOpen() | |
| 513 | - | |
| 514 | - # Execute application | |
| 515 | - app.execute() | |
| 516 | - | |
| 517 | 505 | \ No newline at end of file |
| 506 | + """ | |
| 507 | + Generates TS distribution. | |
| 508 | + """ | |
| 509 | + # Create instance of application | |
| 510 | + app = cstsdist(sys.argv) | |
| 511 | + | |
| 512 | + # Open logfile | |
| 513 | + app.logFileOpen() | |
| 514 | + | |
| 515 | + # Execute application | |
| 516 | + app.execute() | |
| 517 | + | |
| 518 | 518 | \ No newline at end of file | ... | ... |
scripts/cta_kb_bkgrates.py
| ... | ... | @@ -4,7 +4,7 @@ |
| 4 | 4 | # into a column separated file function table. The table is automatically |
| 5 | 5 | # named "bkg_XXX.txt" where "XXX" is for example "kb_E_50h_v3". |
| 6 | 6 | # |
| 7 | -# Copyright (C) 2011 Jurgen Knodlseder | |
| 7 | +# Copyright (C) 2011-2014 Juergen Knoedlseder | |
| 8 | 8 | # |
| 9 | 9 | # This program is free software: you can redistribute it and/or modify |
| 10 | 10 | # it under the terms of the GNU General Public License as published by |
| ... | ... | @@ -29,78 +29,78 @@ import sys |
| 29 | 29 | # Generate file function from model # |
| 30 | 30 | # ================================= # |
| 31 | 31 | def make_file_function(irfname, filename): |
| 32 | - """ | |
| 33 | - Generate file function from model. | |
| 34 | - | |
| 35 | - Parameters: | |
| 36 | - irfname - IRF filename | |
| 37 | - filename - File function filename | |
| 38 | - """ | |
| 39 | - # Open performance file and file function | |
| 40 | - irf = open(irfname, "r") | |
| 41 | - file = open(filename, "w") | |
| 42 | - | |
| 43 | - # Read data | |
| 44 | - for row in irf: | |
| 45 | - | |
| 46 | - # Skip header and trailer | |
| 47 | - if row.find("log(E)") != -1: | |
| 48 | - continue | |
| 49 | - if row.find("--------") != -1: | |
| 50 | - break | |
| 51 | - | |
| 52 | - # Extract data | |
| 53 | - fields = row.replace(" ",",").replace(",,",",").rstrip("\n").split(",") | |
| 54 | - logE = float(fields[0]) | |
| 55 | - aeff = float(fields[1]) | |
| 56 | - r68 = float(fields[2]) | |
| 57 | - r80 = float(fields[3]) | |
| 58 | - eres = float(fields[4]) | |
| 59 | - bgd = float(fields[5]) | |
| 60 | - sens = float(fields[6]) | |
| 61 | - | |
| 62 | - # Compute energy (in MeV) | |
| 63 | - energy = math.pow(10.0, logE)*1.0e6 | |
| 64 | - emin = math.pow(10.0, logE-0.1)*1.0e6 | |
| 65 | - emax = math.pow(10.0, logE+0.1)*1.0e6 | |
| 66 | - ewidth = emax-emin | |
| 67 | - | |
| 68 | - # Compute solid angle of r80 region in sr | |
| 69 | - omega = 2.0 * math.pi * (1.0 - math.cos(math.radians(r80))) | |
| 70 | - | |
| 71 | - # Compute background rate per steradian and MeV | |
| 72 | - bkg_rate = bgd/omega/ewidth | |
| 32 | + """ | |
| 33 | + Generate file function from model. | |
| 34 | + | |
| 35 | + Parameters: | |
| 36 | + irfname - IRF filename | |
| 37 | + filename - File function filename | |
| 38 | + """ | |
| 39 | + # Open performance file and file function | |
| 40 | + irf = open(irfname, "r") | |
| 41 | + file = open(filename, "w") | |
| 42 | + | |
| 43 | + # Read data | |
| 44 | + for row in irf: | |
| 45 | + | |
| 46 | + # Skip header and trailer | |
| 47 | + if row.find("log(E)") != -1: | |
| 48 | + continue | |
| 49 | + if row.find("--------") != -1: | |
| 50 | + break | |
| 51 | + | |
| 52 | + # Extract data | |
| 53 | + fields = row.replace(" ",",").replace(",,",",").rstrip("\n").split(",") | |
| 54 | + logE = float(fields[0]) | |
| 55 | + aeff = float(fields[1]) | |
| 56 | + r68 = float(fields[2]) | |
| 57 | + r80 = float(fields[3]) | |
| 58 | + eres = float(fields[4]) | |
| 59 | + bgd = float(fields[5]) | |
| 60 | + sens = float(fields[6]) | |
| 61 | + | |
| 62 | + # Compute energy (in MeV) | |
| 63 | + energy = math.pow(10.0, logE)*1.0e6 | |
| 64 | + emin = math.pow(10.0, logE-0.1)*1.0e6 | |
| 65 | + emax = math.pow(10.0, logE+0.1)*1.0e6 | |
| 66 | + ewidth = emax-emin | |
| 67 | + | |
| 68 | + # Compute solid angle of r80 region in sr | |
| 69 | + omega = 2.0 * math.pi * (1.0 - math.cos(math.radians(r80))) | |
| 70 | + | |
| 71 | + # Compute background rate per steradian and MeV | |
| 72 | + bkg_rate = bgd/omega/ewidth | |
| 73 | 73 | |
| 74 | - # Write | |
| 75 | - file.write(str(energy)+" "+str(bkg_rate)+"\n") | |
| 76 | - | |
| 77 | - # Close files | |
| 78 | - irf.close() | |
| 79 | - file.close() | |
| 80 | - | |
| 81 | - # Return | |
| 82 | - return | |
| 74 | + # Write | |
| 75 | + file.write(str(energy)+" "+str(bkg_rate)+"\n") | |
| 76 | + | |
| 77 | + # Close files | |
| 78 | + irf.close() | |
| 79 | + file.close() | |
| 80 | + | |
| 81 | + # Return | |
| 82 | + return | |
| 83 | 83 | |
| 84 | 84 | |
| 85 | 85 | # ================ # |
| 86 | 86 | # Main entry point # |
| 87 | 87 | # ================ # |
| 88 | 88 | if __name__ == '__main__': |
| 89 | - """ | |
| 90 | - Main entry point | |
| 91 | - """ | |
| 92 | - # Get IRF from command line argument | |
| 93 | - if (len(sys.argv) > 1): | |
| 94 | - irf = sys.argv[1] | |
| 95 | - else: | |
| 96 | - irf = "kb_E_50h_v3" | |
| 89 | + """ | |
| 90 | + Main entry point | |
| 91 | + """ | |
| 92 | + # Get IRF from command line argument | |
| 93 | + if (len(sys.argv) > 1): | |
| 94 | + irf = sys.argv[1] | |
| 95 | + else: | |
| 96 | + irf = "kb_E_50h_v3" | |
| 97 | 97 | |
| 98 | - # Set parameters | |
| 99 | - caldb = "/usr/local/gamma/share/caldb/cta" | |
| 100 | - | |
| 101 | - # Set filenames | |
| 102 | - irfname = caldb+"/"+irf+".dat" | |
| 103 | - filename = "bkg_"+irf+".txt" | |
| 104 | - | |
| 105 | - # Read | |
| 106 | - make_file_function(irfname, filename) | |
| 98 | + # Set parameters | |
| 99 | + caldb = "/usr/local/gamma/share/caldb/cta" | |
| 100 | + | |
| 101 | + # Set filenames | |
| 102 | + irfname = caldb+"/"+irf+".dat" | |
| 103 | + filename = "bkg_"+irf+".txt" | |
| 104 | + | |
| 105 | + # Read | |
| 106 | + make_file_function(irfname, filename) | ... | ... |
scripts/cta_make_nodes.py
| ... | ... | @@ -4,7 +4,7 @@ |
| 4 | 4 | # logarithmically spaced energy bins. The intensity scale is set to the |
| 5 | 5 | # HESS Crab intensity (assuming a power law). |
| 6 | 6 | # |
| 7 | -# Copyright (C) 2012 Juergen Knoedlseder | |
| 7 | +# Copyright (C) 2012-2014 Juergen Knoedlseder | |
| 8 | 8 | # |
| 9 | 9 | # This program is free software: you can redistribute it and/or modify |
| 10 | 10 | # it under the terms of the GNU General Public License as published by |
| ... | ... | @@ -29,91 +29,91 @@ import math |
| 29 | 29 | # Write one node # |
| 30 | 30 | # ============== # |
| 31 | 31 | def write_node(file, energy, scale): |
| 32 | - """ | |
| 33 | - Writes one node to XML file. | |
| 34 | - """ | |
| 35 | - # Convert to strings | |
| 36 | - str_energy = str(energy) | |
| 37 | - str_scale = str(scale) | |
| 32 | + """ | |
| 33 | + Writes one node to XML file. | |
| 34 | + """ | |
| 35 | + # Convert to strings | |
| 36 | + str_energy = str(energy) | |
| 37 | + str_scale = str(scale) | |
| 38 | 38 | |
| 39 | - # Write start tag | |
| 40 | - file.write(' <node>\n') | |
| 39 | + # Write start tag | |
| 40 | + file.write(' <node>\n') | |
| 41 | 41 | |
| 42 | - # Write energy | |
| 43 | - file.write(' <parameter scale="1e6" name="Energy"') | |
| 44 | - file.write(' min="'+str_energy+'" max="'+str_energy+'"') | |
| 45 | - file.write(' value="'+str_energy+'"') | |
| 46 | - file.write(' free="0"/>\n') | |
| 42 | + # Write energy | |
| 43 | + file.write(' <parameter scale="1e6" name="Energy"') | |
| 44 | + file.write(' min="'+str_energy+'" max="'+str_energy+'"') | |
| 45 | + file.write(' value="'+str_energy+'"') | |
| 46 | + file.write(' free="0"/>\n') | |
| 47 | 47 | |
| 48 | - # Write intensity | |
| 49 | - file.write(' <parameter scale="'+str_scale+'" name="Intensity"') | |
| 50 | - file.write(' min="1e-5" max="1e5"') | |
| 51 | - file.write(' value="1.0"') | |
| 52 | - file.write(' free="1"/>\n') | |
| 48 | + # Write intensity | |
| 49 | + file.write(' <parameter scale="'+str_scale+'" name="Intensity"') | |
| 50 | + file.write(' min="1e-5" max="1e5"') | |
| 51 | + file.write(' value="1.0"') | |
| 52 | + file.write(' free="1"/>\n') | |
| 53 | 53 | |
| 54 | - # Write end tag | |
| 55 | - file.write(' </node>\n') | |
| 54 | + # Write end tag | |
| 55 | + file.write(' </node>\n') | |
| 56 | 56 | |
| 57 | - # Return | |
| 58 | - return | |
| 59 | - | |
| 57 | + # Return | |
| 58 | + return | |
| 59 | + | |
| 60 | 60 | |
| 61 | 61 | # ============ # |
| 62 | 62 | # Create nodes # |
| 63 | 63 | # ============ # |
| 64 | 64 | def create_nodes(emin, emax, enumbins): |
| 65 | - """ | |
| 66 | - Create nodes (energies in TeV). | |
| 67 | - """ | |
| 68 | - # Open file | |
| 69 | - file = open("nodes.xml", "w") | |
| 65 | + """ | |
| 66 | + Create nodes (energies in TeV). | |
| 67 | + """ | |
| 68 | + # Open file | |
| 69 | + file = open("nodes.xml", "w") | |
| 70 | 70 | |
| 71 | - # Set node boundaries | |
| 72 | - elogmin = math.log10(float(emin)) | |
| 73 | - elogmax = math.log10(float(emax)) | |
| 74 | - elogbin = (elogmax - elogmin)/(float(enumbins)-1.0) | |
| 75 | - | |
| 76 | - # Fill arrays | |
| 77 | - for i in range(int(enumbins)): | |
| 78 | - | |
| 79 | - # Compute energy | |
| 80 | - energy = math.pow(10.0, i*elogbin+elogmin) | |
| 81 | - | |
| 82 | - # Compute scale (HESS Crab spectrum) | |
| 83 | - scale = 3.45e-17 * math.pow(energy, -2.63) | |
| 84 | - | |
| 85 | - # Write node | |
| 86 | - write_node(file, energy, scale) | |
| 87 | - | |
| 88 | - # Debug | |
| 89 | - #sys.stdout.write(energy) | |
| 71 | + # Set node boundaries | |
| 72 | + elogmin = math.log10(float(emin)) | |
| 73 | + elogmax = math.log10(float(emax)) | |
| 74 | + elogbin = (elogmax - elogmin)/(float(enumbins)-1.0) | |
| 75 | + | |
| 76 | + # Fill arrays | |
| 77 | + for i in range(int(enumbins)): | |
| 78 | + | |
| 79 | + # Compute energy | |
| 80 | + energy = math.pow(10.0, i*elogbin+elogmin) | |
| 81 | + | |
| 82 | + # Compute scale (HESS Crab spectrum) | |
| 83 | + scale = 3.45e-17 * math.pow(energy, -2.63) | |
| 84 | + | |
| 85 | + # Write node | |
| 86 | + write_node(file, energy, scale) | |
| 87 | + | |
| 88 | + # Debug | |
| 89 | + #sys.stdout.write(energy) | |
| 90 | 90 | #sys.stdout.write(math.pow(10.0, int(math.log10(scale))-1.0)±"\n") |
| 91 | - | |
| 92 | - # Close file | |
| 93 | - file.close() | |
| 94 | - | |
| 95 | - # Return | |
| 96 | - return | |
| 97 | - | |
| 91 | + | |
| 92 | + # Close file | |
| 93 | + file.close() | |
| 94 | + | |
| 95 | + # Return | |
| 96 | + return | |
| 97 | + | |
| 98 | 98 | |
| 99 | 99 | # ======================= # |
| 100 | 100 | # Main script entry point # |
| 101 | 101 | # ======================= # |
| 102 | 102 | if __name__ == '__main__': |
| 103 | - """ | |
| 104 | - Compute nodes. | |
| 105 | - """ | |
| 106 | - # Check command line | |
| 107 | - usage = "Usage: cta_make_nodes emin emax enumbins" | |
| 108 | - if len(sys.argv) < 3: | |
| 109 | - sys.stdout.write(usage+"\n") | |
| 110 | - sys.exit() | |
| 111 | - | |
| 112 | - # Extract parameters | |
| 113 | - emin = sys.argv[1] | |
| 114 | - emax = sys.argv[2] | |
| 115 | - enumbins = sys.argv[3] | |
| 103 | + """ | |
| 104 | + Compute nodes. | |
| 105 | + """ | |
| 106 | + # Check command line | |
| 107 | + usage = "Usage: cta_make_nodes emin emax enumbins" | |
| 108 | + if len(sys.argv) < 3: | |
| 109 | + sys.stdout.write(usage+"\n") | |
| 110 | + sys.exit() | |
| 111 | + | |
| 112 | + # Extract parameters | |
| 113 | + emin = sys.argv[1] | |
| 114 | + emax = sys.argv[2] | |
| 115 | + enumbins = sys.argv[3] | |
| 116 | 116 | |
| 117 | - # Create nodes | |
| 118 | - create_nodes(emin, emax, enumbins) | |
| 119 | - | |
| 117 | + # Create nodes | |
| 118 | + create_nodes(emin, emax, enumbins) | |
| 119 | + | ... | ... |
scripts/cta_root2irf.py
| ... | ... | @@ -11,7 +11,7 @@ |
| 11 | 11 | # area (i.e. the area before applying any theta cut). This is required by |
| 12 | 12 | # GammaLib as the maximum likelihood analysis does not imply any theta cut. |
| 13 | 13 | # |
| 14 | -# Copyright (C) 2011 Jurgen Knodlseder | |
| 14 | +# Copyright (C) 2011-2014 Juergen Knoedlseder | |
| 15 | 15 | # |
| 16 | 16 | # This program is free software: you can redistribute it and/or modify |
| 17 | 17 | # it under the terms of the GNU General Public License as published by | ... | ... |