def test_isValid():

    fd, path = tempfile.mkstemp()

    def raiseWarning(warningString):
        generalTF = SOFAGeneralTF(path, 'r')
        with pytest.warns(SOFAWarning) as record:
            assert not generalTF.isValid()
        assert warningString in str(record[-1].message)
        generalTF.close()

    ## Validity of SOFAFile

    # File not valid
    rootgrp = Dataset(path, 'w', format='NETCDF4')
    rootgrp.close()
    raiseWarning('Missing required attribute: APIName')
    os.remove(path)

    # SOFA File valid
    rootgrp = Dataset(path, 'w', format='NETCDF4')
    # Attributes
    rootgrp.Conventions = 'SOFA'
    rootgrp.Version = '1.0'
    rootgrp.SOFAConventions = 'GeneralFIRE'
    rootgrp.SOFAConventionsVersion = '0.1'
    rootgrp.APIName = 'pysofaconventions'
    rootgrp.APIVersion = '0.1'
    rootgrp.APIVersion = '0.1'
    rootgrp.AuthorContact = '*****@*****.**'
    rootgrp.Organization = 'Eurecat - UPF'
    rootgrp.License = 'WTFPL - Do What the F**k You Want to Public License'
    rootgrp.DataType = 'FIRE'
    rootgrp.RoomType = 'reverberant'
    rootgrp.DateCreated = time.ctime(time.time())
    rootgrp.DateModified = time.ctime(time.time())
    rootgrp.Title = 'testpysofaconventions'
    # Dimensions
    rootgrp.createDimension('I', 1)
    rootgrp.createDimension('N', 2)
    rootgrp.createDimension('C', 3)
    rootgrp.createDimension('M', 4)
    rootgrp.createDimension('R', 5)
    rootgrp.createDimension('E', 6)
    # Variables
    sr = rootgrp.createVariable('Data.SamplingRate', 'f8', ('I', ))
    sr.Units = 'hertz'
    rootgrp.createVariable('Data.Delay', 'f8', ('M', 'R', 'E'))
    rootgrp.createVariable('Data.IR', 'f8', ('M', 'R', 'E', 'N'))
    listenerPositionVar = rootgrp.createVariable('ListenerPosition', 'f8',
                                                 ('I', 'C'))
    listenerPositionVar.Units = 'metre'
    listenerPositionVar.Type = 'cartesian'
    sourcePositionVar = rootgrp.createVariable('SourcePosition', 'f8',
                                               ('I', 'C'))
    sourcePositionVar.Units = 'metre'
    sourcePositionVar.Type = 'cartesian'
    receiverPositionVar = rootgrp.createVariable('ReceiverPosition', 'f8',
                                                 ('R', 'C', 'I'))
    receiverPositionVar.Units = 'metre'
    receiverPositionVar.Type = 'cartesian'
    emitterPositionVar = rootgrp.createVariable('EmitterPosition', 'f8',
                                                ('E', 'C', 'M'))
    emitterPositionVar.Units = 'metre'
    emitterPositionVar.Type = 'cartesian'
    rootgrp.close()

    ## Specific validity

    # Data type should be FIR
    raiseWarning('DataType is not "TF", got: "FIRE"')
    # Adjust data type and required variables to change
    rootgrp = Dataset(path, 'a')
    rootgrp.DataType = 'TF'
    rootgrp.createVariable('Data.Real', 'f8', ('M', 'R', 'N'))
    rootgrp.createVariable('Data.Imag', 'f8', ('M', 'R', 'N'))
    n = rootgrp.createVariable('N', 'f8', ('N', ))
    n.Units = 'hertz'

    rootgrp.close()

    # SOFAConventions should be GeneralTF
    raiseWarning('SOFAConventions is not "GeneralTF", got: "GeneralFIRE"')
    rootgrp = Dataset(path, 'a')
    rootgrp.SOFAConventions = 'GeneralTF'
    rootgrp.close()

    # All right
    generalTF = SOFAGeneralTF(path, 'r')
    assert generalTF.isValid()
    generalTF.close()
    os.remove(path)
import soundfile as sf

#----------Create it----------#

filePath = "/Volumes/Dinge/SOFA/S3A/AudioBooth.sofa"
rootgrp = Dataset(filePath, 'w', format='NETCDF4')

#----------Required Attributes----------#

rootgrp.Conventions = 'SOFA'
rootgrp.Version = SOFAAPI.getAPIVersion()
rootgrp.SOFAConventions = 'AmbisonicsDRIR'
rootgrp.SOFAConventionsVersion = SOFAAmbisonicsDRIR.getConventionVersion()
rootgrp.APIName = 'pysofaconventions'
rootgrp.APIVersion = SOFAAPI.getAPIVersion()
rootgrp.AuthorContact = '*****@*****.**'
rootgrp.Organization = 'Eurecat - UPF'
rootgrp.License = 'Please ask authors for permission'
rootgrp.DataType = 'FIRE'
rootgrp.RoomType = 'reverberant'
rootgrp.DateCreated = time.ctime(time.time())
rootgrp.DateModified = time.ctime(time.time())
rootgrp.Title = 'AudioBooth'
rootgrp.AmbisonicsOrder = '1'

#----------Required Dimensions----------#

M = 1
N = 65536
R = 4
E = 17
Example #3
0
def test_isValid():

    fd, path = tempfile.mkstemp()

    def raiseWarning(warningString):
        ambisonicsDRIR = SOFAAmbisonicsDRIR(path, 'r')
        with pytest.warns(SOFAWarning) as record:
            assert not ambisonicsDRIR.isValid()
        assert warningString in str(record[-1].message)
        ambisonicsDRIR.close()

    ## Validity of SOFAFile

    # File not valid
    rootgrp = Dataset(path, 'w', format='NETCDF4')
    rootgrp.close()
    raiseWarning('Missing required attribute: APIName')
    os.remove(path)

    # SOFA File valid
    rootgrp = Dataset(path, 'w', format='NETCDF4')
    # Attributes
    rootgrp.Conventions = 'SOFA'
    rootgrp.Version = '1.0'
    rootgrp.SOFAConventions = 'GeneralFIR'
    rootgrp.SOFAConventionsVersion = '0.2'
    rootgrp.APIName = 'pysofaconventions'
    rootgrp.APIVersion = '0.1'
    rootgrp.APIVersion = '0.1'
    rootgrp.AuthorContact = '*****@*****.**'
    rootgrp.Organization = 'Eurecat - UPF'
    rootgrp.License = 'WTFPL - Do What the F**k You Want to Public License'
    rootgrp.DataType = 'FIRE'
    rootgrp.RoomType = 'reverberant'
    rootgrp.DateCreated = time.ctime(time.time())
    rootgrp.DateModified = time.ctime(time.time())
    rootgrp.Title = 'testpysofaconventions'
    # Dimensions
    rootgrp.createDimension('I', 1)
    rootgrp.createDimension('N', 2)
    rootgrp.createDimension('C', 3)
    rootgrp.createDimension('M', 4)
    rootgrp.createDimension('R', 5)
    rootgrp.createDimension('E', 6)
    # Variables
    sr = rootgrp.createVariable('Data.SamplingRate', 'f8', ('I', ))
    sr.Units = 'hertz'
    rootgrp.createVariable('Data.Delay', 'f8', ('M', 'R', 'E'))
    rootgrp.createVariable('Data.IR', 'f8', ('M', 'R', 'E', 'N'))
    listenerPositionVar = rootgrp.createVariable('ListenerPosition', 'f8',
                                                 ('I', 'C'))
    listenerPositionVar.Units = 'metre'
    listenerPositionVar.Type = 'cartesian'
    sourcePositionVar = rootgrp.createVariable('SourcePosition', 'f8',
                                               ('I', 'C'))
    sourcePositionVar.Units = 'metre'
    sourcePositionVar.Type = 'cartesian'
    receiverPositionVar = rootgrp.createVariable('ReceiverPosition', 'f8',
                                                 ('R', 'C', 'I'))
    receiverPositionVar.Units = 'metre'
    receiverPositionVar.Type = 'cartesian'
    emitterPositionVar = rootgrp.createVariable('EmitterPosition', 'f8',
                                                ('E', 'C', 'M'))
    emitterPositionVar.Units = 'metre'
    emitterPositionVar.Type = 'cartesian'
    rootgrp.close()

    ## Specific validity

    # SOFAConventions should be AmbisonicsDRIR
    raiseWarning('SOFAConventions is not "AmbisonicsDRIR", got: "GeneralFIR"')
    rootgrp = Dataset(path, 'a')
    rootgrp.SOFAConventions = 'AmbisonicsDRIR'
    rootgrp.close()

    # Required global attribute AmbisonicsOrder
    raiseWarning('Missing required Global Attribute "AmbisonicsOrder"')
    rootgrp = Dataset(path, 'a')
    rootgrp.AmbisonicsOrder = 1
    rootgrp.close()

    # Required attribute Data.IR:ChannelOrdering
    raiseWarning('Missing required Data.IR Attribute "ChannelOrdering"')
    rootgrp = Dataset(path, 'a')
    dataIR = rootgrp.variables['Data.IR']
    dataIR.ChannelOrdering = 'fuma'
    rootgrp.close()

    # Required attribute Data.IR:Normalization
    raiseWarning('Missing required Data.IR Attribute "Normalization"')
    rootgrp = Dataset(path, 'a')
    dataIR = rootgrp.variables['Data.IR']
    dataIR.Normalization = 'fuma'
    rootgrp.close()

    # Requiered variables ListenerUp and ListenerView
    raiseWarning('Missing required Variables "ListenerUp" and "ListenerView"')
    rootgrp = Dataset(path, 'a')
    up = rootgrp.createVariable('ListenerUp', 'f8', ('I', 'C'))
    up.Units = 'metre'
    up.Type = 'cartesian'
    view = rootgrp.createVariable('ListenerView', 'f8', ('I', 'C'))
    view.Units = 'metre'
    view.Type = 'cartesian'
    rootgrp.close()

    # Requiered variables SourceUp and SourceView
    raiseWarning('Missing required Variables "SourceUp" and "SourceView"')
    rootgrp = Dataset(path, 'a')
    up = rootgrp.createVariable('SourceUp', 'f8', ('I', 'C'))
    up.Units = 'metre'
    up.Type = 'cartesian'
    view = rootgrp.createVariable('SourceView', 'f8', ('I', 'C'))
    view.Units = 'metre'
    view.Type = 'cartesian'
    rootgrp.close()

    # All right
    ambisonicsDRIR = SOFAAmbisonicsDRIR(path, 'r')
    assert ambisonicsDRIR.isValid()
    ambisonicsDRIR.close()
    os.remove(path)

    # Test separately the data type (renaming it on the fly might crash the netcdf4)
    rootgrp = Dataset(path, 'w', format='NETCDF4')
    # Attributes
    rootgrp.Conventions = 'SOFA'
    rootgrp.Version = '1.0'
    rootgrp.SOFAConventions = 'GeneralFIR'
    rootgrp.SOFAConventionsVersion = '0.2'
    rootgrp.APIName = 'pysofaconventions'
    rootgrp.APIVersion = '0.1'
    rootgrp.APIVersion = '0.1'
    rootgrp.AuthorContact = '*****@*****.**'
    rootgrp.Organization = 'Eurecat - UPF'
    rootgrp.License = 'WTFPL - Do What the F**k You Want to Public License'
    rootgrp.DataType = 'FIR'
    rootgrp.RoomType = 'reverberant'
    rootgrp.DateCreated = time.ctime(time.time())
    rootgrp.DateModified = time.ctime(time.time())
    rootgrp.Title = 'testpysofaconventions'
    # Dimensions
    rootgrp.createDimension('I', 1)
    rootgrp.createDimension('N', 2)
    rootgrp.createDimension('C', 3)
    rootgrp.createDimension('M', 4)
    rootgrp.createDimension('R', 5)
    rootgrp.createDimension('E', 6)
    # Variables
    sr = rootgrp.createVariable('Data.SamplingRate', 'f8', ('I', ))
    sr.Units = 'hertz'
    rootgrp.createVariable('Data.Delay', 'f8', ('M', 'R'))
    rootgrp.createVariable('Data.IR', 'f8', ('M', 'R', 'N'))
    listenerPositionVar = rootgrp.createVariable('ListenerPosition', 'f8',
                                                 ('I', 'C'))
    listenerPositionVar.Units = 'metre'
    listenerPositionVar.Type = 'cartesian'
    sourcePositionVar = rootgrp.createVariable('SourcePosition', 'f8',
                                               ('I', 'C'))
    sourcePositionVar.Units = 'metre'
    sourcePositionVar.Type = 'cartesian'
    receiverPositionVar = rootgrp.createVariable('ReceiverPosition', 'f8',
                                                 ('R', 'C', 'I'))
    receiverPositionVar.Units = 'metre'
    receiverPositionVar.Type = 'cartesian'
    emitterPositionVar = rootgrp.createVariable('EmitterPosition', 'f8',
                                                ('E', 'C', 'M'))
    emitterPositionVar.Units = 'metre'
    emitterPositionVar.Type = 'cartesian'
    rootgrp.close()

    # Data type should be FIRE
    raiseWarning('DataType is not "FIRE", got: "FIR"')
    def write_SOFA_file(self):
        '''
        This methods uses the computed minimum phase HRIRs and saves them into a SOFA format file.

        :return: nothing
        '''

        filename_min_phase = self.HRIR_SOFA_file.getGlobalAttributeValue(
            'DatabaseName') + '_min_phase.sofa'
        print('printing filename: ', filename_min_phase)
        filePath = '../../HRTF_data/' + filename_min_phase

        rootgrp = Dataset(filePath, 'w', format='NETCDF4')

        attributes = self.HRIR_SOFA_file.getGlobalAttributesAsDict()
        print('printing attributes: ', attributes)

        # ----------Required Attributes----------#

        rootgrp.Conventions = attributes["Conventions"]
        rootgrp.Version = attributes["Version"]
        rootgrp.SOFAConventions = attributes["SOFAConventions"]
        rootgrp.SOFAConventionsVersion = attributes["SOFAConventionsVersion"]
        rootgrp.APIName = attributes["APIName"]
        rootgrp.APIVersion = attributes["APIVersion"]
        rootgrp.AuthorContact = attributes["AuthorContact"]
        rootgrp.Organization = attributes["Organization"]
        rootgrp.License = attributes["License"]
        rootgrp.DataType = attributes["DataType"]
        rootgrp.RoomType = attributes["RoomType"]
        rootgrp.DateCreated = attributes["DateCreated"]
        rootgrp.DateModified = attributes["DateModified"]
        rootgrp.Title = attributes["Title"]
        rootgrp.DatabaseName = attributes["DatabaseName"]
        rootgrp.ListenerShortName = attributes["ListenerShortName"]

        # ----------Required Dimensions----------#

        dimensions = self.HRIR_SOFA_file.getDimensionsAsDict()
        print('dimensions: ', dimensions)

        m = dimensions['M'].size
        n = dimensions['N'].size
        r = dimensions['R'].size
        e = dimensions['E'].size
        i = dimensions[
            'I'].size  # I and C are default ones. Their value is constant and fixed
        c = dimensions[
            'C'].size  # same as above https://www.sofaconventions.org/mediawiki/index.php/SOFA_conventions#AnchorDimensions
        rootgrp.createDimension('M', m)
        rootgrp.createDimension('N', n)
        rootgrp.createDimension('E', e)
        rootgrp.createDimension('R', r)
        rootgrp.createDimension('I', i)
        rootgrp.createDimension('C', c)

        # ----------Required Variables----------#

        #--------- Listener Variables ---------#
        listenerPositionVar = rootgrp.createVariable('ListenerPosition', 'f8',
                                                     ('I', 'C'))
        listenerPosUnits, listenerPosType = self.HRIR_SOFA_file.getListenerPositionInfo(
        )
        listenerPos = self.HRIR_SOFA_file.getListenerPositionValues()

        listenerPositionVar.Units = listenerPosUnits
        listenerPositionVar.Type = listenerPosType
        listenerPositionVar[:] = listenerPos

        if self.HRIR_SOFA_file.hasListenerUp():
            listenerUpVar = rootgrp.createVariable('ListenerUp', 'f8',
                                                   ('I', 'C'))
            listenerUpUnits, listenerUpType = self.HRIR_SOFA_file.getListenerUpInfo(
            )
            listenerUp = self.HRIR_SOFA_file.getListenerUpValues()

            if listenerUpType is not None:
                listenerUpVar.Type = listenerUpType
            if listenerUpUnits is not None:
                listenerUpVar.Units = listenerUpUnits

            listenerUpVar[:] = listenerUp

        if self.HRIR_SOFA_file.hasListenerView():
            listenerViewVar = rootgrp.createVariable('ListenerView', 'f8',
                                                     ('I', 'C'))
            listenerViewUnits, listenerViewType = self.HRIR_SOFA_file.getListenerViewInfo(
            )
            listenerView = self.HRIR_SOFA_file.getListenerViewValues()
            if listenerViewType is not None:
                listenerViewVar.Type = listenerViewType
            if listenerViewUnits is not None:
                listenerViewVar.Units = listenerViewUnits
            listenerViewVar[:] = listenerView

        #------ Emitter ------#
        emitterPositionVar = rootgrp.createVariable('EmitterPosition', 'f8',
                                                    ('E', 'C', 'I'))
        emitterPosUnits, emitterPosType = self.HRIR_SOFA_file.getEmitterPositionInfo(
        )
        emitterPos = self.HRIR_SOFA_file.getEmitterPositionValues()

        emitterPositionVar.Units = emitterPosUnits
        emitterPositionVar.Type = emitterPosType
        emitterPositionVar[:] = emitterPos

        #-------- Source ------#
        sourcePositionVar = rootgrp.createVariable('SourcePosition', 'f8',
                                                   ('M', 'C'))
        sourcePosUnits, sourcePosType = self.HRIR_SOFA_file.getSourcePositionInfo(
        )
        sourcePos = self.HRIR_SOFA_file.getSourcePositionValues()
        print('printing source positions: ', sourcePos)
        sourcePositionVar.Units = sourcePosUnits
        sourcePositionVar.Type = sourcePosType
        sourcePositionVar[:] = sourcePos

        if self.HRIR_SOFA_file.hasSourceUp():
            sourceUpVar = rootgrp.createVariable('SourceUp', 'f8', ('I', 'C'))
            sourceUpUnits, sourceUpType = self.HRIR_SOFA_file.getSourceUpInfo()
            sourceUp = self.HRIR_SOFA_file.getSourceUpValues()

            sourceUpVar.Units = sourceUpUnits
            sourceUpVar.Type = sourceUpType
            sourceUpVar[:] = sourceUp

        if self.HRIR_SOFA_file.hasSourceView():
            sourceViewVar = rootgrp.createVariable('SourceView', 'f8',
                                                   ('I', 'C'))
            sourceViewUnits, sourceViewType = self.HRIR_SOFA_file.getSourceViewInfo(
            )
            sourceView = self.HRIR_SOFA_file.getSourceViewValues()

            sourceViewVar.Units = sourceViewUnits
            sourceViewVar.Type = sourceViewType
            sourceViewVar[:] = sourceView

        #------- Receiver -------#

        receiverPositionVar = rootgrp.createVariable('ReceiverPosition', 'f8',
                                                     ('R', 'C', 'I'))
        receiverPosUnits, receiverPosType = self.HRIR_SOFA_file.getReceiverPositionInfo(
        )
        receiverPos = self.HRIR_SOFA_file.getReceiverPositionValues()

        receiverPositionVar.Units = receiverPosUnits
        receiverPositionVar.Type = receiverPosType
        receiverPositionVar[:] = receiverPos

        samplingRateVar = rootgrp.createVariable('Data.SamplingRate', 'f8',
                                                 ('I'))
        samplingRateVar.Units = self.HRIR_SOFA_file.getSamplingRateUnits()
        samplingRateVar[:] = self.HRIR_SOFA_file.getSamplingRate()

        delayVar = rootgrp.createVariable('Data.Delay', 'f8', ('I', 'R'))
        delay = self.HRIR_SOFA_file.getDataDelay()
        delayVar[:, :] = delay

        dataIRVar = rootgrp.createVariable('Data.IR', 'f8', ('M', 'R', 'N'))
        channelOrdering = self.HRIR_SOFA_file.getDataIRChannelOrdering()
        dataNormalization = self.HRIR_SOFA_file.getDataIRNormalization()

        if channelOrdering is not None:
            dataIRVar.ChannelOrdering = channelOrdering
        if dataNormalization is not None:
            dataIRVar.Normalization = dataNormalization

        dataIRVar[:] = self.min_phase_HRIR_data

        # ----------Close it----------#

        rootgrp.close()
def test_isValid():

    fd, path = tempfile.mkstemp()

    def raiseWarning(warningString):
        simpleHeadphoneIR = SOFASimpleHeadphoneIR(path, 'r')
        with pytest.warns(SOFAWarning) as record:
            assert not simpleHeadphoneIR.isValid()
        assert warningString in str(record[-1].message)
        simpleHeadphoneIR.close()

    ## Validity of SOFAFile

    # File not valid
    rootgrp = Dataset(path, 'w', format='NETCDF4')
    rootgrp.close()
    raiseWarning('Missing required attribute: APIName')
    os.remove(path)

    # SOFA File valid
    rootgrp = Dataset(path, 'w', format='NETCDF4')
    # Attributes
    rootgrp.Conventions = 'SOFA'
    rootgrp.Version = '1.0'
    rootgrp.SOFAConventions = 'GeneralFIRE'
    rootgrp.SOFAConventionsVersion = '0.1'
    rootgrp.APIName = 'pysofaconventions'
    rootgrp.APIVersion = '0.1'
    rootgrp.APIVersion = '0.1'
    rootgrp.AuthorContact = '*****@*****.**'
    rootgrp.Organization = 'Eurecat - UPF'
    rootgrp.License = 'WTFPL - Do What the F**k You Want to Public License'
    rootgrp.DataType = 'FIR'
    rootgrp.RoomType = 'reverberant'
    rootgrp.DateCreated = time.ctime(time.time())
    rootgrp.DateModified = time.ctime(time.time())
    rootgrp.Title = 'testpysofaconventions'
    # Dimensions
    rootgrp.createDimension('I', 1)
    rootgrp.createDimension('N', 2)
    rootgrp.createDimension('C', 3)
    rootgrp.createDimension('M', 4)
    rootgrp.createDimension('R', 5)
    rootgrp.createDimension('E', 6)
    # Variables
    sr = rootgrp.createVariable('Data.SamplingRate', 'f8', ('I', ))
    sr.Units = 'hertz'
    rootgrp.createVariable('Data.Delay', 'f8', ('M', 'R'))
    rootgrp.createVariable('Data.IR', 'f8', ('M', 'R', 'N'))
    listenerPositionVar = rootgrp.createVariable('ListenerPosition', 'f8',
                                                 ('I', 'C'))
    listenerPositionVar.Units = 'metre'
    listenerPositionVar.Type = 'cartesian'
    sourcePositionVar = rootgrp.createVariable('SourcePosition', 'f8',
                                               ('I', 'C'))
    sourcePositionVar.Units = 'metre'
    sourcePositionVar.Type = 'cartesian'
    receiverPositionVar = rootgrp.createVariable('ReceiverPosition', 'f8',
                                                 ('R', 'C', 'I'))
    receiverPositionVar.Units = 'metre'
    receiverPositionVar.Type = 'cartesian'
    emitterPositionVar = rootgrp.createVariable('EmitterPosition', 'f8',
                                                ('E', 'C', 'M'))
    emitterPositionVar.Units = 'metre'
    emitterPositionVar.Type = 'cartesian'
    rootgrp.close()

    ## Specific validity

    # SOFAConventions should be SimpleHeadphoneIR
    raiseWarning(
        'SOFAConventions is not "SimpleHeadphoneIR", got: "GeneralFIRE"')
    rootgrp = Dataset(path, 'a')
    rootgrp.SOFAConventions = 'SimpleHeadphoneIR'
    rootgrp.close()

    # Global Attribute RoomType should be 'free field
    raiseWarning('RoomType is not "free field", got: "reverberant"')
    rootgrp = Dataset(path, 'a')
    rootgrp.RoomType = 'free field'
    rootgrp.close()

    # Mandatory Global Attribute ListenerShortName
    raiseWarning('Missing required Global Attribute "ListenerShortName"')
    rootgrp = Dataset(path, 'a')
    rootgrp.ListenerShortName = 'AmazinglyShortName'
    rootgrp.close()

    # Mandatory Global Attribute ListenerDescription
    raiseWarning('Missing required Global Attribute "ListenerDescription"')
    rootgrp = Dataset(path, 'a')
    rootgrp.ListenerDescription = 'the best listener'
    rootgrp.close()

    # Mandatory Global Attribute SourceDescription
    raiseWarning('Missing required Global Attribute "SourceDescription"')
    rootgrp = Dataset(path, 'a')
    rootgrp.SourceDescription = 'source is not as godo'
    rootgrp.close()

    # Mandatory Global Attribute EmitterDescription
    raiseWarning('Missing required Global Attribute "EmitterDescription"')
    rootgrp = Dataset(path, 'a')
    rootgrp.EmitterDescription = 'I like this emitter'
    rootgrp.close()

    # Mandatory Global Attribute DatabaseName
    raiseWarning('Missing required Global Attribute "DatabaseName"')
    rootgrp = Dataset(path, 'a')
    rootgrp.DatabaseName = 'IncredibleDatabase'
    rootgrp.close()

    # Mandatory Global Attribute SourceModel
    raiseWarning('Missing required Global Attribute "SourceModel"')
    rootgrp = Dataset(path, 'a')
    rootgrp.SourceModel = 'this is the source model'
    rootgrp.close()

    # Mandatory Global Attribute SourceManufacturer
    raiseWarning('Missing required Global Attribute "SourceManufacturer"')
    rootgrp = Dataset(path, 'a')
    rootgrp.SourceManufacturer = 'INGSOC'
    rootgrp.close()

    # Mandatory Global Attribute SourceURI
    raiseWarning('Missing required Global Attribute "SourceURI"')
    rootgrp = Dataset(path, 'a')
    rootgrp.SourceURI = 'www.com'
    rootgrp.close()

    # Dimension E should match dimension R
    raiseWarning(
        'Number of emitters (E) and number of receivers (R) do not match, got "6" and "5"'
    )
    rootgrp = Dataset(path, 'a')
    rootgrp.renameDimension('E', 'OLD_E')
    rootgrp.createDimension('E', 5)
    rootgrp.renameVariable('EmitterPosition', 'OLD_EmitterPosition')
    emitterPositionVar = rootgrp.createVariable('EmitterPosition', 'f8',
                                                ('E', 'C', 'M'))
    emitterPositionVar.Units = 'metre'
    emitterPositionVar.Type = 'cartesian'
    rootgrp.close()

    # All right
    simpleHeadphoneIR = SOFASimpleHeadphoneIR(path, 'r')
    assert simpleHeadphoneIR.isValid()
    simpleHeadphoneIR.close()
    os.remove(path)

    # Test separately the data type (renaming it on the fly might crash the netcdf4)
    rootgrp = Dataset(path, 'w', format='NETCDF4')
    # Attributes
    rootgrp.Conventions = 'SOFA'
    rootgrp.Version = '1.0'
    rootgrp.SOFAConventions = 'SimpleHeadphoneIR'
    rootgrp.SOFAConventionsVersion = '0.1'
    rootgrp.APIName = 'pysofaconventions'
    rootgrp.APIVersion = '0.1'
    rootgrp.APIVersion = '0.1'
    rootgrp.AuthorContact = '*****@*****.**'
    rootgrp.Organization = 'Eurecat - UPF'
    rootgrp.License = 'WTFPL - Do What the F**k You Want to Public License'
    rootgrp.DataType = 'FIRE'
    rootgrp.RoomType = 'reverberant'
    rootgrp.DateCreated = time.ctime(time.time())
    rootgrp.DateModified = time.ctime(time.time())
    rootgrp.Title = 'testpysofaconventions'
    # Dimensions
    rootgrp.createDimension('I', 1)
    rootgrp.createDimension('N', 2)
    rootgrp.createDimension('C', 3)
    rootgrp.createDimension('M', 4)
    rootgrp.createDimension('R', 5)
    rootgrp.createDimension('E', 6)
    # Variables
    sr = rootgrp.createVariable('Data.SamplingRate', 'f8', ('I', ))
    sr.Units = 'hertz'
    rootgrp.createVariable('Data.Delay', 'f8', ('M', 'R', 'E'))
    rootgrp.createVariable('Data.IR', 'f8', ('M', 'R', 'E', 'N'))
    listenerPositionVar = rootgrp.createVariable('ListenerPosition', 'f8',
                                                 ('I', 'C'))
    listenerPositionVar.Units = 'metre'
    listenerPositionVar.Type = 'cartesian'
    sourcePositionVar = rootgrp.createVariable('SourcePosition', 'f8',
                                               ('I', 'C'))
    sourcePositionVar.Units = 'metre'
    sourcePositionVar.Type = 'cartesian'
    receiverPositionVar = rootgrp.createVariable('ReceiverPosition', 'f8',
                                                 ('R', 'C', 'I'))
    receiverPositionVar.Units = 'metre'
    receiverPositionVar.Type = 'cartesian'
    emitterPositionVar = rootgrp.createVariable('EmitterPosition', 'f8',
                                                ('E', 'C', 'M'))
    emitterPositionVar.Units = 'metre'
    emitterPositionVar.Type = 'cartesian'
    rootgrp.close()

    # Data type should be FIR
    raiseWarning('DataType is not "FIR", got: "FIRE"')
def test_isValid():

    fd, path = tempfile.mkstemp()

    def raiseWarning(warningString):
        singleRoomDRIR = SOFASingleRoomDRIR(path, 'r')
        with pytest.warns(SOFAWarning) as record:
            assert not singleRoomDRIR.isValid()
        assert warningString in str(record[-1].message)
        singleRoomDRIR.close()

    ## Validity of SOFAFile

    # File not valid
    rootgrp = Dataset(path, 'w', format='NETCDF4')
    rootgrp.close()
    raiseWarning('Missing required attribute: APIName')
    os.remove(path)

    # SOFA File valid
    rootgrp = Dataset(path, 'w', format='NETCDF4')
    # Attributes
    rootgrp.Conventions = 'SOFA'
    rootgrp.Version = '1.0'
    rootgrp.SOFAConventions = 'GeneralFIRE'
    rootgrp.SOFAConventionsVersion = '0.1'
    rootgrp.APIName = 'pysofaconventions'
    rootgrp.APIVersion = '0.1'
    rootgrp.APIVersion = '0.1'
    rootgrp.AuthorContact = '*****@*****.**'
    rootgrp.Organization = 'Eurecat - UPF'
    rootgrp.License = 'WTFPL - Do What the F**k You Want to Public License'
    rootgrp.DataType = 'FIR'
    rootgrp.RoomType = 'free field'
    rootgrp.DateCreated = time.ctime(time.time())
    rootgrp.DateModified = time.ctime(time.time())
    rootgrp.Title = 'testpysofaconventions'
    # Dimensions
    rootgrp.createDimension('I', 1)
    rootgrp.createDimension('N', 2)
    rootgrp.createDimension('C', 3)
    rootgrp.createDimension('M', 4)
    rootgrp.createDimension('R', 5)
    rootgrp.createDimension('E', 6)
    # Variables
    sr = rootgrp.createVariable('Data.SamplingRate', 'f8', ('I', ))
    sr.Units = 'hertz'
    rootgrp.createVariable('Data.Delay', 'f8', ('M', 'R'))
    rootgrp.createVariable('Data.IR', 'f8', ('M', 'R', 'N'))
    listenerPositionVar = rootgrp.createVariable('ListenerPosition', 'f8',
                                                 ('I', 'C'))
    listenerPositionVar.Units = 'metre'
    listenerPositionVar.Type = 'cartesian'
    sourcePositionVar = rootgrp.createVariable('SourcePosition', 'f8',
                                               ('I', 'C'))
    sourcePositionVar.Units = 'metre'
    sourcePositionVar.Type = 'cartesian'
    receiverPositionVar = rootgrp.createVariable('ReceiverPosition', 'f8',
                                                 ('R', 'C', 'I'))
    receiverPositionVar.Units = 'metre'
    receiverPositionVar.Type = 'cartesian'
    emitterPositionVar = rootgrp.createVariable('EmitterPosition', 'f8',
                                                ('E', 'C', 'M'))
    emitterPositionVar.Units = 'metre'
    emitterPositionVar.Type = 'cartesian'
    rootgrp.close()

    ## Specific validity

    # SOFAConventions should be SingleRoomDRIR
    raiseWarning('SOFAConventions is not "SingleRoomDRIR", got: "GeneralFIRE"')
    rootgrp = Dataset(path, 'a')
    rootgrp.SOFAConventions = 'SingleRoomDRIR'
    rootgrp.close()

    # Global Attribute RoomType should be 'reverberant'
    raiseWarning('RoomType is not "reverberant", got: "free field"')
    rootgrp = Dataset(path, 'a')
    rootgrp.RoomType = 'reverberant'
    rootgrp.close()

    # Mandatory Global Attribute RoomDescription
    raiseWarning('Missing required Global Attribute "RoomDescription"')
    rootgrp = Dataset(path, 'a')
    rootgrp.RoomDescription = 'my bedroom'
    rootgrp.close()

    # Requiered variables ListenerUp and ListenerView
    raiseWarning('Missing required Variables "ListenerUp" and "ListenerView"')
    rootgrp = Dataset(path, 'a')
    up = rootgrp.createVariable('ListenerUp', 'f8', ('I', 'C'))
    up.Units = 'metre'
    up.Type = 'cartesian'
    view = rootgrp.createVariable('ListenerView', 'f8', ('I', 'C'))
    view.Units = 'metre'
    view.Type = 'cartesian'
    rootgrp.close()

    # Dimension E should be 1
    raiseWarning('Number of emitters (E) is not "1", got "6"')
    rootgrp = Dataset(path, 'a')
    rootgrp.renameDimension('E', 'OLD_E')
    rootgrp.createDimension('E', 1)
    rootgrp.renameVariable('EmitterPosition', 'OLD_EmitterPosition')
    emitterPositionVar = rootgrp.createVariable('EmitterPosition', 'f8',
                                                ('E', 'C', 'M'))
    emitterPositionVar.Units = 'metre'
    emitterPositionVar.Type = 'cartesian'
    rootgrp.close()

    # All right
    singleRoomDRIR = SOFASingleRoomDRIR(path, 'r')
    assert singleRoomDRIR.isValid()
    singleRoomDRIR.close()
    os.remove(path)

    # Test separately the data type (renaming it on the fly might crash the netcdf4)
    rootgrp = Dataset(path, 'w', format='NETCDF4')
    # Attributes
    rootgrp.Conventions = 'SOFA'
    rootgrp.Version = '1.0'
    rootgrp.SOFAConventions = 'SingleRoomDRIR'
    rootgrp.SOFAConventionsVersion = '0.1'
    rootgrp.APIName = 'pysofaconventions'
    rootgrp.APIVersion = '0.1'
    rootgrp.APIVersion = '0.1'
    rootgrp.AuthorContact = '*****@*****.**'
    rootgrp.Organization = 'Eurecat - UPF'
    rootgrp.License = 'WTFPL - Do What the F**k You Want to Public License'
    rootgrp.DataType = 'FIRE'
    rootgrp.RoomType = 'reverberant'
    rootgrp.DateCreated = time.ctime(time.time())
    rootgrp.DateModified = time.ctime(time.time())
    rootgrp.Title = 'testpysofaconventions'
    rootgrp.RoomDescription = 'my bedroom'
    # Dimensions
    rootgrp.createDimension('I', 1)
    rootgrp.createDimension('N', 2)
    rootgrp.createDimension('C', 3)
    rootgrp.createDimension('M', 4)
    rootgrp.createDimension('R', 5)
    rootgrp.createDimension('E', 1)
    # Variables
    sr = rootgrp.createVariable('Data.SamplingRate', 'f8', ('I', ))
    sr.Units = 'hertz'
    rootgrp.createVariable('Data.Delay', 'f8', ('M', 'R', 'E'))
    rootgrp.createVariable('Data.IR', 'f8', ('M', 'R', 'E', 'N'))
    listenerPositionVar = rootgrp.createVariable('ListenerPosition', 'f8',
                                                 ('I', 'C'))
    listenerPositionVar.Units = 'metre'
    listenerPositionVar.Type = 'cartesian'
    up = rootgrp.createVariable('ListenerUp', 'f8', ('I', 'C'))
    up.Units = 'metre'
    up.Type = 'cartesian'
    view = rootgrp.createVariable('ListenerView', 'f8', ('I', 'C'))
    view.Units = 'metre'
    view.Type = 'cartesian'
    sourcePositionVar = rootgrp.createVariable('SourcePosition', 'f8',
                                               ('I', 'C'))
    sourcePositionVar.Units = 'metre'
    sourcePositionVar.Type = 'cartesian'
    receiverPositionVar = rootgrp.createVariable('ReceiverPosition', 'f8',
                                                 ('R', 'C', 'I'))
    receiverPositionVar.Units = 'metre'
    receiverPositionVar.Type = 'cartesian'
    emitterPositionVar = rootgrp.createVariable('EmitterPosition', 'f8',
                                                ('E', 'C', 'M'))
    emitterPositionVar.Units = 'metre'
    emitterPositionVar.Type = 'cartesian'
    rootgrp.close()

    # Data type should be FIR
    raiseWarning('DataType is not "FIR", got: "FIRE"')
def test_isValid():

    fd, path = tempfile.mkstemp()

    def raiseWarning(warningString):
        simpleFreeFieldHRIR = SOFASimpleFreeFieldHRIR(path, 'r')
        with pytest.warns(SOFAWarning) as record:
            assert not simpleFreeFieldHRIR.isValid()
        assert warningString in str(record[-1].message)
        simpleFreeFieldHRIR.close()


    ## Validity of SOFAFile

    # File not valid
    rootgrp = Dataset(path, 'w', format='NETCDF4')
    rootgrp.close()
    raiseWarning('Missing required attribute: APIName')
    os.remove(path)

    # SOFA File valid
    rootgrp = Dataset(path, 'w', format='NETCDF4')
    # Attributes
    rootgrp.Conventions = 'SOFA'
    rootgrp.Version = '1.0'
    rootgrp.SOFAConventions = 'GeneralFIRE'
    rootgrp.SOFAConventionsVersion = '0.1'
    rootgrp.APIName = 'pysofaconventions'
    rootgrp.APIVersion = '0.1'
    rootgrp.APIVersion = '0.1'
    rootgrp.AuthorContact = '*****@*****.**'
    rootgrp.Organization = 'Eurecat - UPF'
    rootgrp.License = 'WTFPL - Do What the F**k You Want to Public License'
    rootgrp.DataType = 'FIR'
    rootgrp.RoomType = 'reverberant'
    rootgrp.DateCreated = time.ctime(time.time())
    rootgrp.DateModified = time.ctime(time.time())
    rootgrp.Title = 'testpysofaconventions'
    # Dimensions
    rootgrp.createDimension('I', 1)
    rootgrp.createDimension('N', 2)
    rootgrp.createDimension('C', 3)
    rootgrp.createDimension('M', 4)
    rootgrp.createDimension('R', 5)
    rootgrp.createDimension('E', 6)
    # Variables
    sr = rootgrp.createVariable('Data.SamplingRate', 'f8', ('I',))
    sr.Units = 'hertz'
    rootgrp.createVariable('Data.Delay', 'f8', ('M', 'R'))
    rootgrp.createVariable('Data.IR', 'f8', ('M', 'R', 'N'))
    listenerPositionVar = rootgrp.createVariable('ListenerPosition', 'f8', ('I', 'C'))
    listenerPositionVar.Units = 'metre'
    listenerPositionVar.Type = 'cartesian'
    sourcePositionVar = rootgrp.createVariable('SourcePosition', 'f8', ('I', 'C'))
    sourcePositionVar.Units = 'metre'
    sourcePositionVar.Type = 'cartesian'
    receiverPositionVar = rootgrp.createVariable('ReceiverPosition', 'f8', ('R', 'C', 'I'))
    receiverPositionVar.Units = 'metre'
    receiverPositionVar.Type = 'cartesian'
    emitterPositionVar = rootgrp.createVariable('EmitterPosition', 'f8', ('E', 'C', 'M'))
    emitterPositionVar.Units = 'metre'
    emitterPositionVar.Type = 'cartesian'
    rootgrp.close()

    ## Specific validity

    # SOFAConventions should be SimpleFreeFieldHRIR
    raiseWarning('SOFAConventions is not "SimpleFreeFieldHRIR", got: "GeneralFIRE"')
    rootgrp = Dataset(path, 'a')
    rootgrp.SOFAConventions = 'SimpleFreeFieldHRIR'
    rootgrp.close()

    # Global Attribute RoomType should be 'free field
    raiseWarning('RoomType is not "free field", got: "reverberant"')
    rootgrp = Dataset(path, 'a')
    rootgrp.RoomType = 'free field'
    rootgrp.close()

    # Mandatory Global Attribute ListenerShortName
    raiseWarning('Missing required Global Attribute "ListenerShortName"')
    rootgrp = Dataset(path, 'a')
    rootgrp.ListenerShortName = 'AmazinglyShortName'
    rootgrp.close()

    # Mandatory Global Attribute DatabaseName
    raiseWarning('Missing required Global Attribute "DatabaseName"')
    rootgrp = Dataset(path, 'a')
    rootgrp.DatabaseName = 'IncredibleDatabase'
    rootgrp.close()

    # Dimension E should be 1
    raiseWarning('Number of emitters (E) is not "1", got "6"')
    rootgrp = Dataset(path, 'a')
    rootgrp.renameDimension('E','OLD_E')
    rootgrp.createDimension('E',1)
    rootgrp.renameVariable('EmitterPosition','OLD_EmitterPosition')
    emitterPositionVar = rootgrp.createVariable('EmitterPosition', 'f8', ('E', 'C', 'M'))
    emitterPositionVar.Units = 'metre'
    emitterPositionVar.Type = 'cartesian'
    rootgrp.close()

    # Dimension R should be 2
    raiseWarning('Number of receivers (R) is not "2", got "5"')


    # All right
    # Create a new file from scratch, since changing R will break the file coherence and will produce strange crashes...
    rootgrp = Dataset(path, 'w', format='NETCDF4')
    # Attributes
    rootgrp.Conventions = 'SOFA'
    rootgrp.Version = '1.0'
    rootgrp.SOFAConventions = 'SimpleFreeFieldHRIR'
    rootgrp.SOFAConventionsVersion = '0.1'
    rootgrp.APIName = 'pysofaconventions'
    rootgrp.APIVersion = '0.1'
    rootgrp.APIVersion = '0.1'
    rootgrp.AuthorContact = '*****@*****.**'
    rootgrp.Organization = 'Eurecat - UPF'
    rootgrp.License = 'WTFPL - Do What the F**k You Want to Public License'
    rootgrp.DataType = 'FIR'
    rootgrp.RoomType = 'free field'
    rootgrp.DateCreated = time.ctime(time.time())
    rootgrp.DateModified = time.ctime(time.time())
    rootgrp.Title = 'testpysofaconventions'
    rootgrp.ListenerShortName = 'AmazinglyShortName'
    rootgrp.DatabaseName = 'IncredibleDatabase'
    # Dimensions
    rootgrp.createDimension('I', 1)
    rootgrp.createDimension('N', 2)
    rootgrp.createDimension('C', 3)
    rootgrp.createDimension('M', 4)
    rootgrp.createDimension('R', 2)
    rootgrp.createDimension('E', 1)
    # Variables
    sr = rootgrp.createVariable('Data.SamplingRate', 'f8', ('I',))
    sr.Units = 'hertz'
    rootgrp.createVariable('Data.Delay', 'f8', ('M', 'R'))
    rootgrp.createVariable('Data.IR', 'f8', ('M', 'R', 'N'))
    listenerPositionVar = rootgrp.createVariable('ListenerPosition', 'f8', ('I', 'C'))
    listenerPositionVar.Units = 'metre'
    listenerPositionVar.Type = 'cartesian'
    sourcePositionVar = rootgrp.createVariable('SourcePosition', 'f8', ('I', 'C'))
    sourcePositionVar.Units = 'metre'
    sourcePositionVar.Type = 'cartesian'
    receiverPositionVar = rootgrp.createVariable('ReceiverPosition', 'f8', ('R', 'C', 'I'))
    receiverPositionVar.Units = 'metre'
    receiverPositionVar.Type = 'cartesian'
    emitterPositionVar = rootgrp.createVariable('EmitterPosition', 'f8', ('E', 'C', 'M'))
    emitterPositionVar.Units = 'metre'
    emitterPositionVar.Type = 'cartesian'
    rootgrp.close()

    # Check
    simpleFreeFieldHRIR = SOFASimpleFreeFieldHRIR(path, 'r')
    assert simpleFreeFieldHRIR.isValid()
    simpleFreeFieldHRIR.close()
    os.remove(path)


    # Check FIR
    rootgrp = Dataset(path, 'w', format='NETCDF4')
    # Attributes
    rootgrp.Conventions = 'SOFA'
    rootgrp.Version = '1.0'
    rootgrp.SOFAConventions = 'SimpleFreeFieldHRIR'
    rootgrp.SOFAConventionsVersion = '0.1'
    rootgrp.APIName = 'pysofaconventions'
    rootgrp.APIVersion = '0.1'
    rootgrp.APIVersion = '0.1'
    rootgrp.AuthorContact = '*****@*****.**'
    rootgrp.Organization = 'Eurecat - UPF'
    rootgrp.License = 'WTFPL - Do What the F**k You Want to Public License'
    rootgrp.DataType = 'FIRE'
    rootgrp.RoomType = 'free field'
    rootgrp.DateCreated = time.ctime(time.time())
    rootgrp.DateModified = time.ctime(time.time())
    rootgrp.Title = 'testpysofaconventions'
    rootgrp.ListenerShortName = 'AmazinglyShortName'
    rootgrp.DatabaseName = 'IncredibleDatabase'
    # Dimensions
    rootgrp.createDimension('I', 1)
    rootgrp.createDimension('N', 2)
    rootgrp.createDimension('C', 3)
    rootgrp.createDimension('M', 4)
    rootgrp.createDimension('R', 2)
    rootgrp.createDimension('E', 1)
    # Variables
    sr = rootgrp.createVariable('Data.SamplingRate', 'f8', ('I',))
    sr.Units = 'hertz'
    rootgrp.createVariable('Data.Delay', 'f8', ('M', 'R', 'E'))
    rootgrp.createVariable('Data.IR', 'f8', ('M', 'R', 'E', 'N'))
    listenerPositionVar = rootgrp.createVariable('ListenerPosition', 'f8', ('I', 'C'))
    listenerPositionVar.Units = 'metre'
    listenerPositionVar.Type = 'cartesian'
    sourcePositionVar = rootgrp.createVariable('SourcePosition', 'f8', ('I', 'C'))
    sourcePositionVar.Units = 'metre'
    sourcePositionVar.Type = 'cartesian'
    receiverPositionVar = rootgrp.createVariable('ReceiverPosition', 'f8', ('R', 'C', 'I'))
    receiverPositionVar.Units = 'metre'
    receiverPositionVar.Type = 'cartesian'
    emitterPositionVar = rootgrp.createVariable('EmitterPosition', 'f8', ('E', 'C', 'M'))
    emitterPositionVar.Units = 'metre'
    emitterPositionVar.Type = 'cartesian'
    rootgrp.close()

    # Data type should be FIR
    raiseWarning('DataType is not "FIR", got: "FIRE"')