Commit bc55d6e10a47910c8d28acf59f474ecad4773a05

Authored by Jürgen Knödlseder
2 parents bbccb39e d73b7d2e

Merge branch '2274-jupyter-tutorials' into integration

doc/source/_static/download-notebook.jpg 0 → 100644

138 KB

doc/source/admin/release_history/1.5.rst
... ... @@ -29,7 +29,7 @@ Improvements
29 29 Handle On/Off observations by :ref:`cspull`
30 30 * [`2237 <https://cta-redmine.irap.omp.eu/issues/2237>`_] -
31 31 Add ``statistic`` parameters to :ref:`ctbutterfly`, :ref:`cterror`,
32   - :ref:`cttsmap`, :ref:`ctulimit`, :ref:`cslightcrv, :ref:`csphasecrv`,
  32 + :ref:`cttsmap`, :ref:`ctulimit`, :ref:`cslightcrv`, :ref:`csphasecrv`,
33 33 :ref:`cspull`, :ref:`cssens`, :ref:`csspec`, :ref:`cstsdist` and
34 34 :ref:`cstsmapsplit`
35 35 * [`2231 <https://cta-redmine.irap.omp.eu/issues/2231>`_] -
... ... @@ -60,6 +60,6 @@ Clean up
60 60 * [`2237 <https://cta-redmine.irap.omp.eu/issues/2237>`_] -
61 61 Rename :ref:`ctlike` ``stat`` parameter to ``statistic``
62 62 * [`2237 <https://cta-redmine.irap.omp.eu/issues/2237>`_] -
63   - Derive :ref:`cslightcrv, :ref:`csphasecrv`, :ref:`cspull`, :ref:`cssens`,
64   - :ref:`csspec` and :ref:`cttsdist` scripts from ``cslikelihood`` base
  63 + Derive :ref:`cslightcrv`, :ref:`csphasecrv`, :ref:`cspull`, :ref:`cssens`,
  64 + :ref:`csspec` and :ref:`cstsdist` scripts from ``cslikelihood`` base
65 65 class
... ...
doc/source/conf.py
... ... @@ -35,6 +35,15 @@ except:
35 35 'WARNING: Please install it to get fully-functional Sphinx docs.\n'
36 36 'WARNING: https://pypi.python.org/pypi/sphinxcontrib-doxylink\n')
37 37  
  38 +try:
  39 + import nbsphinx
  40 + extensions += ['nbsphinx']
  41 +except:
  42 + print('WARNING: Python package `nbsphinx` not found.\n'
  43 + 'WARNING: Please install it to get fully-functional Sphinx docs.\n'
  44 + 'WARNING: https://nbsphinx.readthedocs.io/\n')
  45 +
  46 +
38 47 # Raw files to be copied over
39 48 #sys.path.append(os.path.abspath('exts'))
40 49 #extensions = ['rawfiles']
... ... @@ -168,6 +177,9 @@ html_domain_indices = False
168 177 # If true, links to the reST sources are added to the pages.
169 178 html_show_sourcelink = False
170 179  
  180 +# The following line makes it possible to download the source as ipynb
  181 +#html_sourcelink_suffix = ''
  182 +
171 183 # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
172 184 html_show_sphinx = False
173 185  
... ...
doc/source/users/index.rst
... ... @@ -3,6 +3,8 @@
3 3 User Documentation
4 4 ==================
5 5  
  6 +This documentation will guide you in the process of using ctools.
  7 +
6 8 .. toctree::
7 9 :maxdepth: 1
8 10  
... ... @@ -10,4 +12,5 @@ User Documentation
10 12 tutorials/index
11 13 user_manual/index
12 14 reference_manual/index
  15 + user_contributed/index
13 16 glossary
... ...
doc/source/users/notebooks.rst 0 → 100644
  1 +.. _notebooks:
  2 +
  3 +Jupyter notebooks:
  4 +
  5 + * :download:`ctools from Python <tutorials/quickstart/ctools-from-python.ipynb>`
... ...
doc/source/users/reference_manual/csspec.rst
... ... @@ -86,9 +86,9 @@ General parameters
86 86 Spectrum generation method.
87 87 ``SLICE``: Slice energy interval into ``enumbins`` independent bins.
88 88 ``NODES``: Replace spectral model by node function with ``enumbins`` nodes.
89   - ``AUTO`` : Automatically select method based on input data. Will use ``SLICE``
90   - for CTA-only observations and ``NODES`` for observations including
91   - non-CTA data.
  89 + ``AUTO`` : Automatically select method based on input data. Will use
  90 + ``SLICE`` for CTA-only observations and ``NODES`` for
  91 + observations including non-CTA data.
92 92  
93 93 ``emin [real]``
94 94 Lower energy limit of events (in TeV).
... ...
doc/source/users/reference_manual/index.rst
... ... @@ -47,6 +47,7 @@ cscripts
47 47 csmodelinfo --- Shows model container content <csmodelinfo>
48 48 csmodelmerge --- Merges several model containers into one file <csmodelmerge>
49 49 csmodelselect --- Select models from model definition file <csmodelselect>
  50 + csmodelsois --- Generate map cube from subset of models <csmodelsois>
50 51 csobsdef --- Generates observation definition file <csobsdef>
51 52 csobsinfo --- Shows observation container content <csobsinfo>
52 53 csobsselect --- Select observations from observation definition file <csobsselect>
... ...
doc/source/users/tutorials/quickstart/index.rst
... ... @@ -22,4 +22,4 @@ examples should take about an hour, so grab some coffee before you start.
22 22 spectrum
23 23 unbinned
24 24 energy_dispersion
25   - python
  25 + ctools-from-python
... ...
doc/source/users/user_contributed/index.rst 0 → 100644
  1 +.. _user_contributed:
  2 +
  3 +User Contributed Material
  4 +=========================
  5 +
  6 +This section of the manual provides examples and Jupyter Notebooks contributed
  7 +by ctools users.
  8 +
... ...
doc/source/users/user_manual/index.rst
... ... @@ -10,3 +10,4 @@ User Manual
10 10 response
11 11 models
12 12 plotting
  13 +
... ...
doc/source/users/user_manual/plotting.rst
... ... @@ -64,3 +64,7 @@ PNG or PDF file after creating it interactively.
64 64 .. _IRIS: http://cxc.cfa.harvard.edu/iris/
65 65 .. _CASSIS: http://cassis.irap.omp.eu/
66 66 .. _VOSpec: http://www.sciops.esa.int/index.php?project=SAT&page=vospec
  67 +
  68 +.. raw:: html
  69 +
  70 + <iframe src="http://nbviewer.jupyter.org/github/davidchall/random-direction/blob/master/Generate_Beam_Directions.ipynb" width="100%" height="800"></iframe>
... ...
doc/source/users/user_manual/python.rst deleted
1   -.. _sec_python:
2   -
3   -Using ctools from Python
4   -------------------------
5   -
6   -Getting started
7   -~~~~~~~~~~~~~~~
8   -
9   -ctools provides a Python module that allows using all tools and scripts as
10   -Python classes.
11   -To use ctools from Python all you have to do is to import the ctools
12   -module into Python.
13   -You should also import the GammaLib module, as ctools without GammaLib is
14   -generally not very useful.
15   -
16   -.. code-block:: python
17   -
18   - >>> import gammalib
19   - >>> import ctools
20   -
21   -To illustrate how to use ctools from Python, below is a working example
22   -of an event list simulation using the :ref:`ctobssim` class.
23   -An instance ``sim`` of the :ref:`ctobssim` class is generated and user
24   -parameters are set for this instance using the ``[ ]`` operator.
25   -See the :ref:`reference` for a list of parameters and their types.
26   -The ``execute()`` method executes the :ref:`ctobssim` class in the same
27   -way as if it were executed from the command line.
28   -
29   -.. code-block:: python
30   -
31   - >>> import ctools
32   - >>> sim = ctools.ctobssim()
33   - >>> sim["inmodel"] = "${CTOOLS}/share/models/crab.xml"
34   - >>> sim["outevents"] = "events.fits"
35   - >>> sim["caldb"] = "prod2"
36   - >>> sim["irf"] = "South_0.5h"
37   - >>> sim["ra"] = 83.63
38   - >>> sim["dec"] = 22.01
39   - >>> sim["rad"] = 5.0
40   - >>> sim["tmin"] = 0.0
41   - >>> sim["tmax"] = 1800.0
42   - >>> sim["emin"] = 0.1
43   - >>> sim["emax"] = 100.0
44   - >>> sim.execute()
45   -
46   -Alternatively, you may "run" the :ref:`ctobssim` tool using
47   -
48   -.. code-block:: python
49   -
50   - >>> sim.run()
51   -
52   -The main difference to the ``execute()`` method is that the ``run()``
53   -will not write the simulated event file to disk.
54   -Why is this useful?
55   -Well, after having typed ``sim.run()`` the :ref:`ctobssim` class still
56   -exists as an object in memory, including all the simulated events.
57   -The :ref:`ctobssim` class has an ``obs()`` method that returns an
58   -observation container that holds the simulated CTA observation with its
59   -associated events.
60   -To visualise this container, type:
61   -
62   -.. code-block:: python
63   -
64   - >>> print(sim.obs())
65   - === GObservations ===
66   - Number of observations ....: 1
67   - Number of models ..........: 2
68   - Number of observed events .: 23099
69   - Number of predicted events : 0
70   -
71   -There is one CTA observation in the container and to visualise the events
72   -in that observation you may type:
73   -
74   -.. code-block:: python
75   -
76   - >>> print(sim.obs()[0].events())
77   - === GCTAEventList ===
78   - Number of events ..........: 23099 (disposed in "events.fits")
79   - Time interval .............: 51544.5 - 51544.5 days
80   - === GEbounds ===
81   - Number of intervals .......: 1
82   - Energy range ..............: 100 GeV - 100 TeV
83   - === GCTARoi ===
84   - ROI centre ................: RA=83.63, DEC=22.01 [0,0]
85   - ROI radius ................: 5 deg
86   -
87   -The ``obs()[0]`` operator returns the first observation in the observation
88   -container, the ``events()`` operator returns the event list in that
89   -observation.
90   -To see what kind of object you actually got, use:
91   -
92   -.. code-block:: python
93   -
94   - >>> type(sim.obs()[0].events())
95   - <class 'gammalib.cta.GCTAEventList'>
96   -
97   -The CTA event list is implement by the ``GCTAEventList`` class in the
98   -``cta`` module of GammaLib.
99   -To visualise the individual events you can iterate over the events using a
100   -for loop.
101   -This will show the simulated celestial coordinates (RA, DEC), the
102   -coordinate in the camera system [DETX, DETY], energies and
103   -terrestrial times (TT) of all events.
104   -
105   -.. code-block:: python
106   -
107   - >>> events = sim.obs()[0].events()
108   - >>> for event in events:
109   - ... print(event)
110   - ...
111   - Dir=RA=83.6308, DEC=21.8881 [-0.00212759,1.33661e-05] Energy=106.465 GeV Time=-3.15576e+08 s (TT)
112   - Dir=RA=83.7518, DEC=21.8064 [-0.0035525,0.00197398] Energy=117.706 GeV Time=-3.15576e+08 s (TT)
113   - Dir=RA=83.5545, DEC=22.0933 [0.00145377,-0.00122121] Energy=138.624 GeV Time=-3.15576e+08 s (TT)
114   - ...
115   -
116   -
117   -Performing a maximum likelihood analysis in Python
118   -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
119   -
120   -We can now benefit from the fact that we have some simulated events in
121   -memory to fit a model to these events using the :ref:`ctlike` class.
122   -We will do this in unbinned mode.
123   -Here is what you have to do:
124   -
125   -.. code-block:: python
126   -
127   - >>> like = ctools.ctlike(sim.obs())
128   - >>> like.run()
129   -
130   -This is pretty compact.
131   -Where are the user parameters?
132   -:ref:`ctlike` doesn't in fact need any as all the relevant information is
133   -already contained in the observation container produced by the
134   -:ref:`ctobssim` class.
135   -And you may have recognised that we constructed the :ref:`ctlike`
136   -instance by using the :ref:`ctobssim` observation container as
137   -constructor argument.
138   -
139   -To check how the fit went you can inspect the optimiser used by
140   -:ref:`ctlike`:
141   -
142   -.. code-block:: python
143   -
144   - >>> print(like.opt())
145   - === GOptimizerLM ===
146   - Optimized function value ..: 154553.422
147   - Absolute precision ........: 0.005
148   - Acceptable value decrease .: 2
149   - Optimization status .......: converged
150   - Number of parameters ......: 10
151   - Number of free parameters .: 4
152   - Number of iterations ......: 2
153   - Lambda ....................: 1e-05
154   -
155   -Apparently, the fit converged after 2 iterations.
156   -Out of 10 parameters in the model 4 have been fitted (the others were kept
157   -fixed).
158   -To inspect the fit results you can print the model container that is a
159   -member of the observation container:
160   -
161   -.. code-block:: python
162   -
163   - >>> print(like.obs().models())
164   - === GModels ===
165   - Number of models ..........: 2
166   - Number of parameters ......: 10
167   - === GModelSky ===
168   - Name ......................: Crab
169   - Instruments ...............: all
170   - Instrument scale factors ..: unity
171   - Observation identifiers ...: all
172   - Model type ................: PointSource
173   - Model components ..........: "PointSource" * "PowerLaw" * "Constant"
174   - Number of parameters ......: 6
175   - Number of spatial par's ...: 2
176   - RA .......................: 83.6331 [-360,360] deg (fixed,scale=1)
177   - DEC ......................: 22.0145 [-90,90] deg (fixed,scale=1)
178   - Number of spectral par's ..: 3
179   - Prefactor ................: 5.82698e-16 +/- 1.02186e-17 [1e-23,1e-13] ph/cm2/s/MeV (free,scale=1e-16,gradient)
180   - Index ....................: -2.47534 +/- 0.0154764 [-0,-5] (free,scale=-1,gradient)
181   - PivotEnergy ..............: 300000 [10000,1e+09] MeV (fixed,scale=1e+06,gradient)
182   - Number of temporal par's ..: 1
183   - Normalization ............: 1 (relative value) (fixed,scale=1,gradient)
184   - === GCTAModelIrfBackground ===
185   - Name ......................: CTABackgroundModel
186   - Instruments ...............: CTA
187   - Instrument scale factors ..: unity
188   - Observation identifiers ...: all
189   - Model type ................: "PowerLaw" * "Constant"
190   - Number of parameters ......: 4
191   - Number of spectral par's ..: 3
192   - Prefactor ................: 1.01266 +/- 0.0119676 [0.001,1000] ph/cm2/s/MeV (free,scale=1,gradient)
193   - Index ....................: 0.00474762 +/- 0.00731725 [-5,5] (free,scale=1,gradient)
194   - PivotEnergy ..............: 1e+06 [10000,1e+09] MeV (fixed,scale=1e+06,gradient)
195   - Number of temporal par's ..: 1
196   - Normalization ............: 1 (relative value) (fixed,scale=1,gradient)
197   -
198   -Suppose you want to repeat the fit by optimising also the position of the
199   -point source.
200   -This is easy from Python:
201   -
202   -.. code-block:: python
203   -
204   - >>> like.obs().models()["Crab"]["RA"].free()
205   - >>> like.obs().models()["Crab"]["DEC"].free()
206   - >>> like.run()
207   - >>> print(like.obs().models())
208   - ...
209   - RA .......................: 83.6327 +/- 0.000916983 [-360,360] deg (free,scale=1)
210   - DEC ......................: 22.0141 +/- 0.00086378 [-90,90] deg (free,scale=1)
211   -
212   -The ``like.obs().models()`` method provides the model container, using the
213   -``["Crab"]`` operator we access the Crab model in that container and using
214   -the ``["RA"]`` and ``["DEC"]`` methods we access the relevant model
215   -parameters.
216   -The ``free()`` method frees a parameter, the opposite would be a call to
217   -the ``fix()`` method.
218   -
219   -.. warning::
220   -
221   - Passing observation containers between ctools classes is a very
222   - convenient and powerful way of building in-memory analysis pipelines.
223   - However, this implies that you need some computing ressources when
224   - dealing with large observation containers (for example if you want to
225   - analyse a few 100 hours of data at once).
226   -
227   -.. warning::
228   -
229   - You have to be aware about the scope of the objects you're
230   - dealing with.
231   - In the above example, the ``sim.obs()`` container is allocated by the
232   - :ref:`ctobssim` class, hence it disappears (a.k.a. goes out of scope)
233   - once the :ref:`ctobssim` class is deleted, as illustrated by the
234   - following example:
235   -
236   - .. code-block:: python
237   -
238   - >>> obs = sim.obs()
239   - >>> del sim
240   - >>> print(obs)
241   - Segmentation fault
242   -
243   - Note that
244   -
245   - .. code-block:: python
246   -
247   - >>> obs = sim.obs()
248   - >>> del sim
249   - >>> print(like.obs())
250   - === GObservations ===
251   - Number of observations ....: 1
252   - Number of models ..........: 2
253   - Number of observed events .: 23099
254   - Number of predicted events : 23099
255   -
256   - is okay as the ``ctools.ctlike(sim.obs())`` constructor will create
257   - a copy of the observation container that lives within the :ref:`ctlike`
258   - instance.
259   - To preserve an observation container after a ctools object goes out
260   - of scope you have to create a local copy of the container using the
261   - ``copy()`` method:
262   -
263   - .. code-block:: python
264   -
265   - >>> obs = sim.obs().copy()
266   - >>> del sim
267   - >>> print(obs)
268   - === GObservations ===
269   - Number of observations ....: 1
270   - Number of models ..........: 2
271   - Number of observed events .: 23099
272   - Number of predicted events : 0
273   -
274   -
275   -Using obsutils
276   -~~~~~~~~~~~~~~
277   -
278   -ctools provides the Python module ``obsutils`` that may further simplify
279   -your analysis efforts.
280   -``obsutils`` is a Python script that makes use of the GammaLib and ctools
281   -modules to create standard analysis steps.
282   -As all Python scripts, ``obsutils`` is part of the cscripts module that
283   -is imported using
284   -
285   -.. code-block:: python
286   -
287   - >>> import cscripts
288   -
289   -Here an example of how to use ``obsutils``:
290   -
291   -.. code-block:: python
292   -
293   - >>> import gammalib
294   - >>> import ctools
295   - >>> from cscripts import obsutils
296   - >>> pattern = obsutils.set_obs_patterns("four", ra=83.63, dec=22.01, offset=1.0)
297   - >>> obs = obsutils.set_obs_list(pattern, duration=1800, emin=0.1, emax=100.0, rad=5.0, caldb="prod2", irf="South_0.5h")
298   - >>> print(obs)
299   - === GObservations ===
300   - Number of observations ....: 4
301   - Number of models ..........: 0
302   - Number of observed events .: 0
303   - Number of predicted events : 0
304   - >>> obs.models(gammalib.GModels("${CTOOLS}/share/models/crab.xml"))
305   - >>> obs = obsutils.sim(obs)
306   - >>> like = ctools.ctlike(obs)
307   - >>> like.run()
308   - >>> print(like.obs().models())
309   - === GModels ===
310   - Number of models ..........: 2
311   - Number of parameters ......: 10
312   - ...
313   -
314   -The module is imported using the ``from cscripts import obsutils`` directive.
315   -The ``obsutils.set_obs_patterns()`` function will create a pointing
316   -pattern of four observations located at offset angles of 1 degree from the
317   -nominal location of the Crab nebula.
318   -The ``obsutils.set_obs_list()`` will build an observation container from
319   -that pattern where each pointing will have a duration of 1800 seconds,
320   -cover the 0.1-100 TeV energy range and a field of view of 5°.
321   -The ``South_0.5h`` IRF from the Prod2 calibration database will be used.
322   -A model is then appended to the observation container using the
323   -``obs.models()`` method.
324   -The ``obsutils.sim()`` function then simulates the event data and returns
325   -an observation container with the simulated observations.
326   -The observation container is then passed to ``ctlike`` for maximum likelihood
327   -fitting.
328   -
329   -
330   -Access analysis results
331   -~~~~~~~~~~~~~~~~~~~~~~~
332   -
333   -Here are some examples that show how to access your analysis results in
334   -python.
335   -In the following it is assumed that you have a ctlike object called
336   -``like`` which is setup and runs:
337   -
338   -.. code-block:: python
339   -
340   - import gammalib
341   - import ctools
342   - like = ctools.ctlike(sim.obs())
343   - like.run()
344   -
345   -* Best-fit parameters:
346   -
347   - The following command shows how to access the fit parameters and errors:
348   -
349   - .. code-block:: python
350   -
351   - obs = like.obs() # Get observations object
352   - obs.models()["Crab"]["Prefactor"].value() # This returns the actual fit value
353   - obs.models()["Crab"]["Prefactor"].error() # This returns the actual fit error
354   -
355   -* Open XML model file from python and print models on screen:
356   -
357   - .. code-block:: python
358   -
359   - models = gammalib.GModels("$CTOOLS/share/models/crab.xml")
360   - print(models)
361   -
362   -* Likelihood value
363   -
364   - .. code-block:: python
365   -
366   - logL = like.opt().value() # Returns log-likelihood value
367   - print(logL)
368   -
369   - or alternatively
370   -
371   - .. code-block:: python
372   -
373   - logL = like.obs().function().value() # Returns log-likelihood value
374   - print(logL)
375   -
376   -* Curvature Matrix (aka Hessian)
377   -
378   - .. code-block:: python
379   -
380   - curvature = like.obs().function().curvature() # Return GMatrixSparse object
381   - print(curvature)
382   -
383   - To get the covariance matrix, the curvature matrix needs to be
384   - inverted:
385   -
386   - .. code-block:: python
387   -
388   - covariance = curvature.invert()
389   - print(covariance)
390   -
391   -
392   -Modify and work on XML models
393   -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
394   -
395   -* Fix a certain parameter
396   -
397   - .. code-block:: python
398   -
399   - models["Crab"]["Prefactor"].fix()
400   -
401   -* Release a certain parameter
402   -
403   - .. code-block:: python
404   -
405   - models["Crab"]["Prefactor"].free()
406   -
407   -* Check if parameter is free
408   -
409   - .. code-block:: python
410   -
411   - if models["Crab"]["Prefactor"].is_free():
412   - ...
413   -
414   -* Set parameter value
415   -
416   - .. code-block:: python
417   -
418   - models["Crab"]["Index"].value(-2.5)
419   -
420   -* Set parameter boundaries
421   -
422   - .. code-block:: python
423   -
424   - models["Crab"]["Index"].min(-5.0)
425   - models["Crab"]["Index"].max(-1.0)
426   -
427   - or quicker
428   -
429   - .. code-block:: python
430   -
431   - models["Crab"]["Index"].range(-5.0,-1.0)
432   -
433   -* Loop over models and parameters (e.g. fix all parameters)
434   -
435   - .. code-block:: python
436   -
437   - for model in models: # Loop over models
438   - for par in model: # Loop over parameters
439   - par.fix() # fix parameter
440   -
441   -* Save modified XML model
442   -
443   - .. code-block:: python
444   -
445   - models.save("my_model.xml")
446   -
447   -
448   -Beyond the first steps
449   -~~~~~~~~~~~~~~~~~~~~~~
450   -
451   -You now have learned the basics of using ctools and GammaLib within Python.
452   -To go beyond these initial steps you may check the Python scripts in the
453   -``examples`` folder that provide useful analysis examples.
454   -Check the ``README.md`` file in that folder for an explanation of the scripts.