Commit 4622f176b41ac59c502f8c128e2e894f576d54db

Authored by Jürgen Knödlseder
1 parent 77e1bab8

Integrate code

cscripts/Makefile.am
@@ -157,38 +157,42 @@ testdata = $(top_srcdir)/test/data/crab.xml \ @@ -157,38 +157,42 @@ testdata = $(top_srcdir)/test/data/crab.xml \
157 $(top_srcdir)/test/data/model_mapcube.fits.gz \ 157 $(top_srcdir)/test/data/model_mapcube.fits.gz \
158 $(top_srcdir)/test/data/iact_runlist.dat \ 158 $(top_srcdir)/test/data/iact_runlist.dat \
159 $(top_srcdir)/test/data/iact_runlist_1.dat \ 159 $(top_srcdir)/test/data/iact_runlist_1.dat \
160 - $(top_srcdir)/test/data/iact_runlist_1.dat 160 + $(top_srcdir)/test/data/iact_runlist_2.dat
161 161
162 # Test data to be distributed in $(pyexecdir)/cscripts/tests/data/iactdata 162 # Test data to be distributed in $(pyexecdir)/cscripts/tests/data/iactdata
163 testiactdata = $(top_srcdir)/test/data/iactdata/hdu-index.fits.gz \ 163 testiactdata = $(top_srcdir)/test/data/iactdata/hdu-index.fits.gz \
164 $(top_srcdir)/test/data/iactdata/master.json \ 164 $(top_srcdir)/test/data/iactdata/master.json \
165 - $(top_srcdir)/test/data/iactdata/obs-index.fits.gz \  
166 - $(top_srcdir)/test/data/iactdata/events/irf_file.fits.gz \  
167 - $(top_srcdir)/test/data/iactdata/events/events_0.fits.gz \  
168 - $(top_srcdir)/test/data/iactdata/events/events_1.fits.gz \  
169 - $(top_srcdir)/test/data/iactdata/events/events_2.fits.gz \  
170 - $(top_srcdir)/test/data/iactdata/events/events_3.fits.gz \  
171 - $(top_srcdir)/test/data/iactdata/events/events_4.fits.gz \  
172 - $(top_srcdir)/test/data/iactdata/events/events_5.fits.gz \  
173 - $(top_srcdir)/test/data/iactdata/events/events_6.fits.gz \  
174 - $(top_srcdir)/test/data/iactdata/events/events_7.fits.gz \  
175 - $(top_srcdir)/test/data/iactdata/events/events_8.fits.gz 165 + $(top_srcdir)/test/data/iactdata/obs-index.fits.gz
  166 +
  167 +# Test data to be distributed in $(pyexecdir)/cscripts/tests/data/iactdata/events
  168 +testiactevents = $(top_srcdir)/test/data/iactdata/events/irf_file.fits.gz \
  169 + $(top_srcdir)/test/data/iactdata/events/events_0.fits.gz \
  170 + $(top_srcdir)/test/data/iactdata/events/events_1.fits.gz \
  171 + $(top_srcdir)/test/data/iactdata/events/events_2.fits.gz \
  172 + $(top_srcdir)/test/data/iactdata/events/events_3.fits.gz \
  173 + $(top_srcdir)/test/data/iactdata/events/events_4.fits.gz \
  174 + $(top_srcdir)/test/data/iactdata/events/events_5.fits.gz \
  175 + $(top_srcdir)/test/data/iactdata/events/events_6.fits.gz \
  176 + $(top_srcdir)/test/data/iactdata/events/events_7.fits.gz \
  177 + $(top_srcdir)/test/data/iactdata/events/events_8.fits.gz
176 178
177 # Install scripts, parfiles, test scripts and test data. Note that we don't 179 # Install scripts, parfiles, test scripts and test data. Note that we don't
178 # need to prepend $(DESTDIR) here (not fully clear why, but that's the way 180 # need to prepend $(DESTDIR) here (not fully clear why, but that's the way
179 # it is) 181 # it is)
180 -binscriptsdir = $(bindir)  
181 -binscripts_DATA = $(binscripts)  
182 -pythonscriptsdir = $(pyexecdir)/cscripts  
183 -pythonscripts_DATA = $(pythonscripts)  
184 -pfilesdir = $(prefix)/syspfiles  
185 -pfiles_DATA = $(parfiles)  
186 -testscriptsdir = $(pyexecdir)/cscripts/tests  
187 -testscripts_DATA = $(testscripts)  
188 -testdatadir = $(pyexecdir)/cscripts/tests/data  
189 -testdata_DATA = $(testdata)  
190 -testiactdatadir = $(pyexecdir)/cscripts/tests/data/iactdata  
191 -testiactdata_DATA = $(testiactdata) 182 +binscriptsdir = $(bindir)
  183 +binscripts_DATA = $(binscripts)
  184 +pythonscriptsdir = $(pyexecdir)/cscripts
  185 +pythonscripts_DATA = $(pythonscripts)
  186 +pfilesdir = $(prefix)/syspfiles
  187 +pfiles_DATA = $(parfiles)
  188 +testscriptsdir = $(pyexecdir)/cscripts/tests
  189 +testscripts_DATA = $(testscripts)
  190 +testdatadir = $(pyexecdir)/cscripts/tests/data
  191 +testdata_DATA = $(testdata)
  192 +testiactdatadir = $(pyexecdir)/cscripts/tests/data/iactdata
  193 +testiactdata_DATA = $(testiactdata)
  194 +testiacteventsdir = $(pyexecdir)/cscripts/tests/data/iactdata/events
  195 +testiactevents_DATA = $(testiactdata)
192 196
193 # Files to be distributed in the tar file 197 # Files to be distributed in the tar file
194 EXTRA_DIST = $(binscripts) $(pythonscripts) $(parfiles) \ 198 EXTRA_DIST = $(binscripts) $(pythonscripts) $(parfiles) \
cscripts/csiactobs.py
@@ -172,8 +172,10 @@ class csiactobs(ctools.cscript): @@ -172,8 +172,10 @@ class csiactobs(ctools.cscript):
172 172
173 # Check if prodname is present 173 # Check if prodname is present
174 if self._prodname == config['name']: 174 if self._prodname == config['name']:
175 - self._hdu_index = str(os.path.join(self._datapath, config['hduindx']))  
176 - self._obs_index = str(os.path.join(self._datapath, config['obsindx'])) 175 + self._hdu_index = str(os.path.join(self._datapath,
  176 + config['hduindx']))
  177 + self._obs_index = str(os.path.join(self._datapath,
  178 + config['obsindx']))
177 179
178 # Leave loop if index file names were found 180 # Leave loop if index file names were found
179 break 181 break
@@ -292,7 +294,9 @@ class csiactobs(ctools.cscript): @@ -292,7 +294,9 @@ class csiactobs(ctools.cscript):
292 spec = gammalib.GModelSpectralNodes() 294 spec = gammalib.GModelSpectralNodes()
293 295
294 # Create logarithmic energy nodes 296 # Create logarithmic energy nodes
295 - bounds = gammalib.GEbounds(self._bkgpars,gammalib.GEnergy(emin,'TeV'),gammalib.GEnergy(emax,'TeV'), True) 297 + bounds = gammalib.GEbounds(self._bkgpars,
  298 + gammalib.GEnergy(emin,'TeV'),
  299 + gammalib.GEnergy(emax,'TeV'), True)
296 300
297 # Loop over bounds and set intensity value 301 # Loop over bounds and set intensity value
298 for i in range(bounds.size()): 302 for i in range(bounds.size()):
@@ -319,7 +323,8 @@ class csiactobs(ctools.cscript): @@ -319,7 +323,8 @@ class csiactobs(ctools.cscript):
319 # Return spectrum 323 # Return spectrum
320 return spec 324 return spec
321 325
322 - def _iact_background(self, telescope, obs_id, bkg_scale, bkgtype, emin=0.01, emax=100): 326 + def _iact_background(self, telescope, obs_id, bkg_scale, bkgtype,
  327 + emin=0.01, emax=100):
323 """ 328 """
324 Create an IACT background model 329 Create an IACT background model
325 330
@@ -348,27 +353,35 @@ class csiactobs(ctools.cscript): @@ -348,27 +353,35 @@ class csiactobs(ctools.cscript):
348 prefactor *= bkg_scale 353 prefactor *= bkg_scale
349 354
350 # Create background spectrum 355 # Create background spectrum
351 - spec = self._background_spectrum(prefactor, index, emin, emax) 356 + spec = self._background_spectrum(prefactor, index, emin, emax)
352 357
353 - # Create background model instance 358 + # Create background model
354 bck = gammalib.GCTAModelIrfBackground(spec) 359 bck = gammalib.GCTAModelIrfBackground(spec)
355 360
356 # Set AeffBackground 361 # Set AeffBackground
357 elif bkgtype == 'aeff': 362 elif bkgtype == 'aeff':
  363 +
  364 + # Set background components
358 prefactor = bkg_scale * self._bkg_aeff_norm 365 prefactor = bkg_scale * self._bkg_aeff_norm
359 - spec = self._background_spectrum(prefactor, self._bkg_aeff_index, emin, emax) 366 + spec = self._background_spectrum(prefactor,
  367 + self._bkg_aeff_index,
  368 + emin, emax)
360 369
361 - # Create background model instance 370 + # Create background model
362 bck = gammalib.GCTAModelAeffBackground(spec) 371 bck = gammalib.GCTAModelAeffBackground(spec)
363 372
364 # Set Gaussian Background 373 # Set Gaussian Background
365 elif bkgtype == 'gauss': 374 elif bkgtype == 'gauss':
  375 +
  376 + # Set background components
366 prefactor = bkg_scale * self._bkg_gauss_norm 377 prefactor = bkg_scale * self._bkg_gauss_norm
367 -  
368 - # Create background spectrum  
369 - spec = self._background_spectrum(prefactor, self._bkg_gauss_index, emin, emax) 378 + spec = self._background_spectrum(prefactor,
  379 + self._bkg_gauss_index,
  380 + emin, emax)
370 radial = gammalib.GCTAModelRadialGauss(self._bkg_gauss_sigma) 381 radial = gammalib.GCTAModelRadialGauss(self._bkg_gauss_sigma)
371 - bck = gammalib.GCTAModelRadialAcceptance(radial, spec) 382 +
  383 + # Create background model
  384 + bck = gammalib.GCTAModelRadialAcceptance(radial, spec)
372 385
373 else: 386 else:
374 msg = 'Background type "'+bkgtype+'" unsupported' 387 msg = 'Background type "'+bkgtype+'" unsupported'
@@ -422,7 +435,7 @@ class csiactobs(ctools.cscript): @@ -422,7 +435,7 @@ class csiactobs(ctools.cscript):
422 Write observation summary 435 Write observation summary
423 """ 436 """
424 # Log header 437 # Log header
425 - self._log_header1(gammalib.TERSE, 'Observation summary') 438 + self._log_header1(gammalib.NORMAL, 'Observation summary')
426 439
427 # Set energy range dependent on whether boundaries exist or 440 # Set energy range dependent on whether boundaries exist or
428 # not 441 # not
@@ -444,16 +457,16 @@ class csiactobs(ctools.cscript): @@ -444,16 +457,16 @@ class csiactobs(ctools.cscript):
444 457
445 Parameters 458 Parameters
446 ---------- 459 ----------
447 - hdu : `gammalib.GFitsTable` 460 + hdu : `~gammalib.GFitsTable`
448 HDU FITS table 461 HDU FITS table
449 - hierarchy : list of strings 462 + hierarchy : list of str
450 List of strings containing the hierarchy how to look for files 463 List of strings containing the hierarchy how to look for files
451 - formats : list of strings 464 + formats : list of str
452 File formats available for this observation 465 File formats available for this observation
453 466
454 Returns 467 Returns
455 ------- 468 -------
456 - filename : string 469 + filename : str
457 Filename of requested file 470 Filename of requested file
458 """ 471 """
459 472
@@ -477,8 +490,8 @@ class csiactobs(ctools.cscript): @@ -477,8 +490,8 @@ class csiactobs(ctools.cscript):
477 # Build filename from information stored in hduindx_hdu 490 # Build filename from information stored in hduindx_hdu
478 if index >= 0: 491 if index >= 0:
479 filename = os.path.join(self._subdir, 492 filename = os.path.join(self._subdir,
480 - hdu['FILE_DIR'][index],  
481 - hdu['FILE_NAME'][index]) 493 + hdu['FILE_DIR'][index],
  494 + hdu['FILE_NAME'][index])
482 filehdu = hdu['HDU_NAME'][index] 495 filehdu = hdu['HDU_NAME'][index]
483 filename += '['+filehdu+']' 496 filename += '['+filehdu+']'
484 497
@@ -492,17 +505,17 @@ class csiactobs(ctools.cscript): @@ -492,17 +505,17 @@ class csiactobs(ctools.cscript):
492 505
493 Parameters 506 Parameters
494 ---------- 507 ----------
495 - filename : string 508 + filename : str
496 Filename 509 Filename
497 obs_id : int 510 obs_id : int
498 Observation ID 511 Observation ID
499 - filetype : string 512 + filetype : str
500 Type of file 513 Type of file
501 514
502 Returns 515 Returns
503 ------- 516 -------
504 present : bool 517 present : bool
505 - Flag signaling if file is present 518 + True if filename is present, False otherwise
506 """ 519 """
507 520
508 # Initialise return value 521 # Initialise return value
@@ -513,17 +526,18 @@ class csiactobs(ctools.cscript): @@ -513,17 +526,18 @@ class csiactobs(ctools.cscript):
513 526
514 # Check if file is empty 527 # Check if file is empty
515 if fname.is_empty(): 528 if fname.is_empty():
516 - self._log_string(gammalib.TERSE, 'Skipping observation '+str(obs_id)+  
517 - ': No '+filetype+' found\n') 529 + msg = 'Skipping observation "%s": No %s found' % (obs_id, filetype)
  530 + self._log_string(gammalib.NORMAL, msg)
518 present = False 531 present = False
519 532
520 # Check if file exists 533 # Check if file exists
521 elif not fname.exists(): 534 elif not fname.exists():
522 - self._log_string(gammalib.TERSE, 'Skipping observation '+str(obs_id)+  
523 - ': '+filetype+' "'+filename+'" does not exist\n') 535 + msg = ('Skipping observation "%s": %s "%s" does not exist' %
  536 + (obs_id, filetype, filename))
  537 + self._log_string(gammalib.NORMAL, msg)
524 present = False 538 present = False
525 539
526 - # Return boolean 540 + # Return present flag
527 return present 541 return present
528 542
529 543
@@ -548,9 +562,8 @@ class csiactobs(ctools.cscript): @@ -548,9 +562,8 @@ class csiactobs(ctools.cscript):
548 lib = self._xml.element('observation_list', 0) 562 lib = self._xml.element('observation_list', 0)
549 563
550 # Log output 564 # Log output
551 - if self._logTerse():  
552 - self._log('\n')  
553 - self._log.header1('Looping over '+str(len(self._runlist))+' runs') 565 + msg = 'Looping over %d runs' % len(self._runlist)
  566 + self._log_header1(gammalib.TERSE, msg)
554 567
555 # Initialise energy range values for logging 568 # Initialise energy range values for logging
556 self._ebounds.clear() 569 self._ebounds.clear()
@@ -562,7 +575,8 @@ class csiactobs(ctools.cscript): @@ -562,7 +575,8 @@ class csiactobs(ctools.cscript):
562 obs_selection = '[OBS_ID=='+str(obs_id)+']' 575 obs_selection = '[OBS_ID=='+str(obs_id)+']'
563 576
564 # Open HDU index file 577 # Open HDU index file
565 - hduindx = gammalib.GFits(self._hdu_index+'[HDU_INDEX]'+obs_selection) 578 + hduindx = gammalib.GFits(self._hdu_index+'[HDU_INDEX]'+
  579 + obs_selection)
566 hduindx_hdu = hduindx['HDU_INDEX'] 580 hduindx_hdu = hduindx['HDU_INDEX']
567 581
568 # Initialise types and formats 582 # Initialise types and formats
@@ -593,8 +607,9 @@ class csiactobs(ctools.cscript): @@ -593,8 +607,9 @@ class csiactobs(ctools.cscript):
593 if not gammalib.GFilename(edispfile).exists(): 607 if not gammalib.GFilename(edispfile).exists():
594 608
595 # Print warning that edisp cannot be used for this observation 609 # Print warning that edisp cannot be used for this observation
596 - self._log_string(gammalib.TERSE, 'Warning: observation '+str(obs_id)+  
597 - ' has no energy dispersion information\n') 610 + msg = ('Warning: observation "%s" has no energy dispersion '
  611 + 'information' % obs_id)
  612 + self._log_string(gammalib.NORMAL, msg)
598 613
599 # Set energy dispersion file as empty 614 # Set energy dispersion file as empty
600 edispfile = '' 615 edispfile = ''
@@ -615,23 +630,27 @@ class csiactobs(ctools.cscript): @@ -615,23 +630,27 @@ class csiactobs(ctools.cscript):
615 # Remove IRF background if file doesnt exist 630 # Remove IRF background if file doesnt exist
616 run_bkg_mod_hierarchy.remove('irf') 631 run_bkg_mod_hierarchy.remove('irf')
617 632
618 - # Print warning that edisp cannot be used for this observation  
619 - self._log_string(gammalib.TERSE, 'Warning: observation '+str(obs_id)+  
620 - ' has no background information (IRF background cannot be used)\n') 633 + # Print warning that edisp cannot be used for this
  634 + # observation
  635 + msg = ('Warning: observation "%s" has no background '
  636 + 'information (IRF background cannot be used)' %
  637 + obs_id)
  638 + self._log_string(gammalib.NORMAL, msg)
621 639
622 # Check if background model hierarchy is empty 640 # Check if background model hierarchy is empty
623 if len(run_bkg_mod_hierarchy) == 0: 641 if len(run_bkg_mod_hierarchy) == 0:
624 642
625 # Skip observation if no background can be used 643 # Skip observation if no background can be used
626 - self._log_string(gammalib.TERSE, 'Skipping observation '+str(obs_id)+  
627 - ': No background can be used\n') 644 + msg = ('Skipping observation "%s": No background can be '
  645 + 'used' % obs_id)
  646 + self._log_string(gammalib.NORMAL, msg)
628 continue 647 continue
629 648
630 else: 649 else:
631 # Log if we fall back to next background approach 650 # Log if we fall back to next background approach
632 - self._log_string(gammalib.TERSE, 'Observation '+str(obs_id)+  
633 - ': Falling back to background "'+  
634 - run_bkg_mod_hierarchy[0]+'"\n') 651 + msg = ('Observation "%s": Falling back to background "%s"' %
  652 + (obs_id, run_bkg_mod_hierarchy[0]))
  653 + self._log_string(gammalib.NORMAL, msg)
635 654
636 # Close hdu index file 655 # Close hdu index file
637 hduindx.close() 656 hduindx.close()
@@ -643,7 +662,8 @@ class csiactobs(ctools.cscript): @@ -643,7 +662,8 @@ class csiactobs(ctools.cscript):
643 if self._use_bkg_scale: 662 if self._use_bkg_scale:
644 663
645 # Read background scale from fits file 664 # Read background scale from fits file
646 - obsindx = gammalib.GFits(self._obs_index+'[OBS_INDEX]'+obs_selection) 665 + obsindx = gammalib.GFits(self._obs_index+'[OBS_INDEX]'+
  666 + obs_selection)
647 bkg_scale = obsindx['OBS_INDEX']['BKG_SCALE'][0] 667 bkg_scale = obsindx['OBS_INDEX']['BKG_SCALE'][0]
648 obsindx.close() 668 obsindx.close()
649 669
@@ -722,17 +742,20 @@ class csiactobs(ctools.cscript): @@ -722,17 +742,20 @@ class csiactobs(ctools.cscript):
722 obs.append(bck) 742 obs.append(bck)
723 743
724 # Log the observation ID and object name that has been appended 744 # Log the observation ID and object name that has been appended
725 - self._log_value(gammalib.TERSE, 'Append observation', '%s ("%s")' %  
726 - (obs_id, object_name)) 745 + self._log_value(gammalib.NORMAL, 'Append observation', '%s ("%s")' %
  746 + (obs_id, object_name))
727 747
728 # Log the file names of the event and response files 748 # Log the file names of the event and response files
729 self._log_value(gammalib.EXPLICIT, ' Event file', eventfile) 749 self._log_value(gammalib.EXPLICIT, ' Event file', eventfile)
730 self._log_value(gammalib.EXPLICIT, ' Effective area file', aefffile) 750 self._log_value(gammalib.EXPLICIT, ' Effective area file', aefffile)
731 - self._log_value(gammalib.EXPLICIT, ' Point spread function file', psffile)  
732 - self._log_value(gammalib.EXPLICIT, ' Energy dispersion file', edispfile) 751 + self._log_value(gammalib.EXPLICIT, ' Point spread function file',
  752 + psffile)
  753 + self._log_value(gammalib.EXPLICIT, ' Energy dispersion file',
  754 + edispfile)
733 self._log_value(gammalib.EXPLICIT, ' Background file', bkgfile) 755 self._log_value(gammalib.EXPLICIT, ' Background file', bkgfile)
734 if self._use_bkg_scale: 756 if self._use_bkg_scale:
735 - self._log_value(gammalib.EXPLICIT, ' Background scale', bkg_scale) 757 + self._log_value(gammalib.EXPLICIT, ' Background scale',
  758 + bkg_scale)
736 759
737 # Append models provided by "inmodel" to the model container 760 # Append models provided by "inmodel" to the model container
738 self._append_inmodels() 761 self._append_inmodels()
@@ -742,8 +765,8 @@ class csiactobs(ctools.cscript): @@ -742,8 +765,8 @@ class csiactobs(ctools.cscript):
742 765
743 # Write warning in no observation could be used from runlist 766 # Write warning in no observation could be used from runlist
744 if lib.size() == 0: 767 if lib.size() == 0:
745 - self._log_string(gammalib.TERSE, 'WARNING: No observation was appended from specified '  
746 - 'runlist\n') 768 + self._log_string(gammalib.NORMAL, 'WARNING: No observation was '
  769 + 'appended from specified runlist')
747 770
748 # Return 771 # Return
749 return 772 return
@@ -772,28 +795,22 @@ class csiactobs(ctools.cscript): @@ -772,28 +795,22 @@ class csiactobs(ctools.cscript):
772 Save observation definition and model definition XML file 795 Save observation definition and model definition XML file
773 """ 796 """
774 # Write header 797 # Write header
775 - if self._logTerse():  
776 - self._log('\n')  
777 - self._log.header1('Save XML files') 798 + self._log_header1(gammalib.TERSE, 'Save XML files')
778 799
779 # Get filenames 800 # Get filenames
780 outobs = self['outobs'].filename() 801 outobs = self['outobs'].filename()
781 outmodel = self['outmodel'].filename() 802 outmodel = self['outmodel'].filename()
782 803
783 - # Log file name  
784 - if self._logTerse():  
785 - self._log(gammalib.parformat('Obs. definition XML file'))  
786 - self._log(outobs.url())  
787 - self._log('\n') 804 + # Log observation definition file name
  805 + self._log_value(gammalib.NORMAL, 'Obs. definition XML file',
  806 + outobs.url())
788 807
789 # Save observation definition XML file 808 # Save observation definition XML file
790 self._xml.save(outobs.url()) 809 self._xml.save(outobs.url())
791 810
792 - # Log file name  
793 - if self._logTerse():  
794 - self._log(gammalib.parformat('Model definiton XML file'))  
795 - self._log(outmodel.url())  
796 - self._log('\n') 811 + # Log model definition file name
  812 + self._log_value(gammalib.NORMAL, 'Model definiton XML file',
  813 + outmodel.url())
797 814
798 # Save model XML file 815 # Save model XML file
799 self._models.save(outmodel.url()) 816 self._models.save(outmodel.url())
cscripts/csobsdef.py
@@ -336,7 +336,7 @@ class csobsdef(ctools.cscript): @@ -336,7 +336,7 @@ class csobsdef(ctools.cscript):
336 # Write observation into logger 336 # Write observation into logger
337 name = obs.instrument()+' observation' 337 name = obs.instrument()+' observation'
338 value = 'Name="%s" ID="%s"' % (obs.name(), obs.id()) 338 value = 'Name="%s" ID="%s"' % (obs.name(), obs.id())
339 - self._log_value(gammalib.TERSE, name, value) 339 + self._log_value(gammalib.NORMAL, name, value)
340 self._log_string(gammalib.EXPLICIT, str(obs)+'\n') 340 self._log_string(gammalib.EXPLICIT, str(obs)+'\n')
341 341
342 # Append observation 342 # Append observation
@@ -394,11 +394,9 @@ class csobsdef(ctools.cscript): @@ -394,11 +394,9 @@ class csobsdef(ctools.cscript):
394 obs : `~gammalib.GObservations` 394 obs : `~gammalib.GObservations`
395 Observation container 395 Observation container
396 """ 396 """
397 -  
398 # Return container 397 # Return container
399 return self._obs 398 return self._obs
400 399
401 -  
402 def pntdef(self, csv): 400 def pntdef(self, csv):
403 """ 401 """
404 Set pointing definition from a CSV table 402 Set pointing definition from a CSV table