IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Sep 10, 2010, 9:39:28 AM (16 years ago)
Author:
Serge CHASTEL
Message:

Unstable. Added logging (no tused yet. p2 is currently very slow

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/sc_branches/psps_testing/testers/fits/p2.py

    r29116 r29140  
    1 
     1from psi.psi_inquisitor import PsiInquisitor
     2import pyfits
     3from StringIO import StringIO
     4from utilities.util import match
    25
    36class P2FitsTester:
    47    """
     8    The content of a P2 frame data is detailed in PSDC-940-006-01,
     9    paragraph 3.6.3, item 1).
     10
    511    This is the class that tests the contents of a P2 FITS file
    6     provided by IPP. The contents can be checked against the database
     12    provided by IPP. The contents are checked against the database
    713    through SOAP queries.
     14
     15    Note that the purpose of this class is NOT to test the FITS
     16    validity (which can be checked using some pyfits options).
    817    """
    9     def __init__(self, fitsFile):
    10         self.fits = fitsFile
     18    def __init__(self, fits_file, psi_configuration):
     19        """
     20        Creates a P2FitsTester object.
     21
     22        >>> import pyfits
     23        >>> fits_file = pyfits.open('data/psut/ok/fits/p2_was_00105439.FITS')
     24        >>> psi_configuration = 'psi.web01_configuration'
     25        >>> p2ft = P2FitsTester(fits_file, psi_configuration)
     26        """
     27        self.fits = fits_file
     28        self.psi_inquisitor = PsiInquisitor(psi_configuration)
    1129
    1230    def test(self):
    13         return ("BARF", None)
     31        """
     32        Tests a FITS file supposed to contain a P2 frame data set.
     33
     34        >>> import pyfits
     35        >>> fits_file = pyfits.open('data/psut/ok/fits/p2_was_00105439.FITS')
     36        >>> psi_configuration = 'psi.web01_configuration'
     37        >>> p2ft = P2FitsTester(fits_file, psi_configuration)
     38        >>> (message, values) = p2ft.test()
     39        >>> print message # doctest:+ELLIPSIS
     40        PSDC-940-006-01, 3.6.3, 1): OK
     41        PSDC-940-006-01, 3.6.6.8: OK
     42        PSDC-940-006-01, TBD_test_detections_frames: OK (frame 00 - SELECT * FROM ImageMeta WHERE imageID = 10543901)
     43        PSDC-940-006-01, TBD_test_detections_frames: OK (frame 01 - SELECT * FROM ImageMeta WHERE imageID = 10543902)
     44        ...
     45        PSDC-940-006-01, TBD_test_detections_frames: OK (frame 57 - SELECT * FROM ImageMeta WHERE imageID = 10543976)
     46        >>> print values
     47        None
     48        """
     49        report = StringIO()
     50        # 1. There is no image for the PrimaryHDU (at 0)
     51        (messages, other) = self.test_primary()
     52        report.write(messages)
     53        # 2. Look at the FrameMeta information
     54        (messages, values) = self.test_frame_meta()
     55        report.write('\n' + messages)
     56        if values is None:
     57            return (report.getvalue(), None)
     58        # 3. There should be values['ota'] sequences of [ImageMeta,
     59        # Detection, SkinnyObject, ObjectCalColor] frames
     60        frameID = values['frameID']
     61        nOTA = values['nOTA']
     62        if len(self.fits) != 4*nOTA + 2:
     63            report.write('\nInvalid number of OTA: from FITS file: %d / from FrameMeta %d'
     64                         % (len(self.fits)-2/4, nOTA))
     65            return (report.getvalue(), None)
     66        for ota_index in range(nOTA):
     67            (messages, values) = self.test_detections_frames(frameID, ota_index)
     68            report.write('\n' + messages)
     69        return (report.getvalue(), None)
     70
     71    def test_detections_frames(self, frameID, ota_index):
     72        """
     73        Tests the contents of the 4-frame sequence [ImageMeta,
     74        Detection, SkinnyObject, ObjectCalColor].
     75        Those contents can be queried by: TODO
     76       
     77        """
     78        report = StringIO()
     79        # Check that the 4 sequence is correct
     80        requirement = 'PSDC-940-006-01, TBD_test_detections_frames: '
     81        fits_index = 4*ota_index+2
     82        if self.fits[fits_index].name != 'IMAGEMETA':
     83            return (requirement + 'KO (Not an ImageMeta frame)', None)
     84        if self.fits[fits_index+1].name != 'DETECTION':
     85            return (requirement + 'KO (Not a Detection frame)', None)
     86        if self.fits[fits_index+2].name != 'SKINNYOBJECT':
     87            return (requirement + 'KO (Not a SkinnyObject frame)', None)
     88        if self.fits[fits_index+3].name != 'OBJECTCALCOLOR':
     89            return (requirement + 'KO (Not a ObjectCalColor frame)', None)
     90        # Check ImageMeta values (!We get imageID from the FITS file
     91        # since they are not sorted)
     92        imageID = self.fits[fits_index].data.field('imageID')[0]
     93        query = 'SELECT * FROM ImageMeta WHERE imageID = %s' % str(imageID)
     94        answer = self.psi_inquisitor.query(query)
     95        (message, status) = match(self.fits[fits_index].data, answer, requirement)
     96        if status != 0:
     97            return (message + ' (frame %02d - %s)' % (ota_index, query), None)
     98        report.write(message)
     99        # Extract the number of detections
     100        nDetect = int(self.fits[fits_index].data.field('nDetect')[0])
     101        # Check if we have the same number from PSI
     102        query = 'SELECT count(*) AS HowMany FROM Detection WHERE imageID = %s' % str(imageID)
     103        howMany = self.psi_inquisitor.query(query)['items'][0]['HowMany']
     104        if nDetect != howMany:
     105            report.write('\nGot %d Detection items from PSI instead of %d for image %s'
     106                         % (howMany, nDetect, str(imageID)) )
     107        # Get the nDetect detections (they are assumed to be sorted in the FITS file)
     108        query = 'SELECT * FROM Detection WHERE imageID = %s ORDER BY detectID' % str(imageID)
     109        answer = self.psi_inquisitor.query(query)
     110        for detection_index in range(nDetect):
     111            (message, status) = match(self.fits[fits_index+1].data, answer,
     112                                      requirement, detection_index)
     113            report.write('\n' + message)
     114        return (report.getvalue() + ' (frame %02d - %s)' % (ota_index, query), None)
     115
     116    def test_frame_meta(self):
     117        """
     118        Tests the contents of the FrameMeta table.
     119        - 48 columns x 1 row
     120        - This table contains values that are useful, namely: frameID,
     121          nOTA (number of OTA).
     122        - The data can be found in PSI using the query:
     123                   SELECT * FROM FrameMeta WHERE frameID = <frameID>;
     124        """
     125        requirement = 'PSDC-940-006-01, 3.6.6.8: '
     126        if self.fits[1].header['NAXIS'] != 2:
     127            return (requirement + 'KO (NAXIS != 2)', None)
     128        if self.fits[1].header['NAXIS2'] != 1:
     129            return (requirement + 'KO (NAXIS2 != 1)', None)
     130        if self.fits[1].header['TFIELDS'] != 48:
     131            return (requirement + 'KO (TFIELDS != 48)', None)
     132        frameID = self.fits[1].data.field('frameID')[0]
     133        query = "SELECT * FROM FrameMeta WHERE frameID = %d" % frameID
     134        answer = self.psi_inquisitor.query(query)
     135        (message, status) = match(self.fits[1].data, answer, requirement)
     136        if status != 0:
     137            return (message, None)
     138        else:
     139            return (message,
     140                    {'frameID': int(self.fits[1].data.field('frameID')[0]),
     141                     'nOTA': int(self.fits[1].data.field('nOTA')[0]) })
     142   
     143    def test_primary(self):
     144        """
     145        Check that the primary header i.e. fits[0] has no dimension.
     146        """
     147        requirement = 'PSDC-940-006-01, 3.6.3, 1): '
     148        if self.fits[0].header['NAXIS'] != 0:
     149            return (requirement + 'KO', None)
     150        # Add more tests?
     151        return (requirement + 'OK', None)
     152
     153if __name__ == '__main__':
     154    import doctest
     155    doctest.testmod()
Note: See TracChangeset for help on using the changeset viewer.