1

I would like to read a netcdf file using python. This file contain a netcdf variable in the double format.

I know that this quantity should be complex and I know that the last argument is always 2 numbers (real and im).

I would like to read the nedcdf variable IN AN EFFICIENT WAY and allocate it to a complex python/numpy variable.

For the moment I have the following INEFFICIENT program that work:

import numpy as N
self.EIG2D = N.zeros((self.nkpt,self.nband,3,self.natom,3,self.natom),dtype=complex)
EIG2Dtmp = root.variables['second_derivative_eigenenergies'][:,:,:,:,:,:,:] #number_of_atoms, 
                                   # number_of_cartesian_directions, number_of_atoms, number_of_cartesian_directions,
                                   # number_of_kpoints, product_mband_nsppol, cplex
for ikpt in N.arange(nkpt):
  for iband in N.arange(nband):
    for icart in N.arange(3):
      for iatom in N.arange(natom):
        for jcart in N.arange(0,3):
          for jatom in N.arange(natom):
            self.EIG2D[ikpt,iband,icart,iatom,jcart,jatom] = complex(EIG2Dtmp[iatom,icart,jatom,jcart,ikpt,iband,0],\
                                                                     EIG2Dtmp[iatom,icart,jatom,jcart,ikpt,iband,1])

How to make this more efficient ?

Thank you in advance,

Samuel.

sponce
  • 1,279
  • 2
  • 11
  • 17
  • Look into the [netCDF4-python](http://netcdf4-python.googlecode.com/svn/trunk/docs/netCDF4-module.html) module. Are you looping over every index of the `EIG2Dtmp` array? If so, you can just do `self.EIG2D = root.variables[:]` rather than looping through everything. – Spencer Hill May 29 '14 at 14:59
  • I'm not. There are 7 arguments to EIG2Dtmp and 6 to self.EIG2D. The missing one beeing simply the real and im part. – sponce May 29 '14 at 15:04
  • 2
    I see. The accepted answer to [this question](http://stackoverflow.com/questions/2598734/numpy-creating-a-complex-array-from-2-real-ones) seems to be exactly what you need. – Spencer Hill May 29 '14 at 17:31
  • It is worth looking at the rest of the answers to that question. Depending on the array ordering, a simple "complex view" on the same array may suffice, as described in another answer (I unfortunately do not know how to link to a specific answer) – eickenberg May 29 '14 at 18:33
  • @Spencer Hill: It seems to work: numpy.vectorize(complex)(Data[...,0], Data[...,1]). The only issue for me is that I also need to change the ordering A[a,b,c] ==> A[c,b,a] but I should probably made a new thread for that I guess. Thanks a lot ! – sponce May 29 '14 at 21:18
  • No problem. Please post your solution as an answer to your question and then accept it so that this question can be marked as being resolved. – Spencer Hill May 30 '14 at 00:02

1 Answers1

2

Thanks to Spencer Hill, the solution for me was

self.EIG2D = numpy.vectorize(complex)(EIG2Dtmp[...,0], EIG2Dtmp[...,1])

You can also refer to Numpy: Creating a complex array from 2 real ones?

Community
  • 1
  • 1
sponce
  • 1,279
  • 2
  • 11
  • 17