********************** Setting up DDSCAT jobs ********************** A DDSCAT job, which corresponds to a single execution of DDSCAT, is controlled by a :class:`DDscat` object. This is essentially a :class:`Settings` object and :class:`Target` object bound together. The Simplest Case ================= Again, the simplest way to create a new job is by calling the class :class:`DDscat` object with no arguments. This builds a new job, based on defaults. The :class:`Settings` and :class:`Target` that comprise the job are accesible as attributes. >>> job = DDscat() >>> job.settings >>> job.target Assembling Settings and Targets =============================== More typically you will construct :class:`Settings` and :class:`Target` first and then combine them into a :class:`DDscat` job. >>> s = Settings() >>> s.NAMBIENT = 1.333 >>> t = targets.ELLIPSOID((0.5, 0.1, 0.1)) >>> job = DDscat(settings = s, target = t) >>> job.settings.NAMBIENT 1.333 >>> job.target.directive 'ELLIPSOID' It is possible to change the settings or target associated with a job afer creation by simple reassignment >>> job = DDscat() >>> job.target >>> new_t = targets.ELLIPSOID((0.1, 0.5, 0.5)) >>> job.target = new_t # Assign a new target >>> job.target Job Attributes ============== DDscat jobs have features that are intended to simplify job management. For instance the class contains attributes for calculating various characteristics to determine the applicability of the DDA to a given simulation. For example it can calculate ``x`` and ``mkd`` defined in the DDSCAT user guide: >>> job.target = targets.ELLIPSOID((0.5,0.1,0.1)) >>> job.mkd array([ 0.82665329, 0.43637804, 0.45623888, 0.61425222, 0.64325583]) >>> job.x array([ 3.68734716, 2.32885084, 1.70185254, 1.34085351, 1.10620415]) The entries correspond to the values at each of the wavelengths of the job. Note that this won't work with generic targets since the number of dipoles they contain is unknown. The method ``info`` gives more information >>> job.info() Target: ELLIPSOID N=6773 aeff=0.176058 d=0.015000 wave mkd x alpha beta -------------------------------------------------------------- [ 0.3 0.82665329 3.68734716 0.21312368 4.45805261] [ 0.475 0.43637804 2.32885084 0.4037311 5.33375841] [ 0.65 0.45623888 1.70185254 0.38615602 3.72807117] [ 0.825 0.61425222 1.34085351 0.2868193 2.18167051] [ 1. 0.64325583 1.10620415 0.27388697 1.71872388] Writing the Job =============== Once you've made all the necessary adjustments to a job you can write it to file with the ``write`` command. This saves the ``ddscat.par`` file, and for a :class:`FROM_FILE` target the ``shape.dat`` file as well: >>> job = DDscat() >>> job.target = targets.Helix(0.5, 0.2, 0.05, 0.02) Generating Helix... Done constructing sweep path... >>> os.listdir('.') # Empty folder [] >>> job.write() # Write the job >>> os.listdir('.') # Two new files ['ddscat.par', 'shape.dat'] >>> !head ddscat.par ===Generated by ScatPy (Thu Aug 1 17:33:41 2013)=== **** Preliminaries **** NOTORQ PBCGS2 GPFAFT GKDLDR NOTBIN **** Initial Memory Allocation **** 100 100 100 **** Target Geometry and Composition **** >>> !head shape.dat FROM_FILE_Helix (0.500000, 0.200000, 0.050000, 0.020000, 0.015000) 344 1 0 0 0 1 0 1 1 1 34.66666667 4.66666667 4.66666667 J JX JY JZ ICOMPX,ICOMPY,ICOMPZ 1 1 6 2 1 1 1 2 1 7 2 1 1 1 3 1 7 3 1 1 1 Reading a Job ============= You can read an old job from file with the ``fromfile`` command. >>> job = DDscat() >>> job.target = targets.Helix(0.5, 0.2, 0.05, 0.02) Generating Helix... Done constructing sweep path... >>> job.write() >>> job.info() Target: FROM_FILE ( ) N=344 aeff=0.065200 d=0.015000 wave mkd x alpha beta -------------------------------------------------------------- [ 0.3 0.82665329 1.36554647 0.07892674 1.65096416] [ 0.475 0.43637804 0.8624504 0.14951496 1.97526695] [ 0.65 0.45623888 0.63025222 0.14300633 1.38062792] [ 0.825 0.61425222 0.49656235 0.10621866 0.80794466] [ 1. 0.64325583 0.40966394 0.10142939 0.63650023] >>> >>> old_job = DDscat.fromfile('ddscat.par') # Read the old job >>> old_job.info() Target: FROM_FILE ( ) N=344 aeff=0.065200 d=0.015000 wave mkd x alpha beta -------------------------------------------------------------- [ 0.3 0.82665277 1.36554561 0.07892674 1.65096416] [ 0.475 0.43637777 0.86244986 0.14951496 1.97526695] [ 0.65 0.45623859 0.63025182 0.14300633 1.38062792] [ 0.825 0.61425183 0.49656204 0.10621866 0.80794466] [ 1. 0.64325542 0.40966368 0.10142939 0.63650023] Running the Job =============== If you have a local version of DDSCAT, you can run the job from within the Python session with ``calculate``. This writes the settings and target to file and starts DDSCAt:: >>> job.calculate() >>> old_job.calculate() >DDSCAT using parameter file= ddscat.par >DDSCAT NUMPROC= 1 >DDSCAT --- DDSCAT 7.2.2 [12.06.05] >DDSCAT Single-precision version >REAPAR ===Generated > **** >REAPAR NOTORQ - do not compute torques >REAPAR PBCGS2 - CCG Method >REAPAR GPFAFT - using GPFA package from Clive Temperton >REAPAR GKDLDR - Gutkowicz-Krusin & . ... . >GETFML Q_abs = 2.0146E-02 Q_ext= 2.0152E-02 >SCAT 214 scattering directions used to calculate , etc. >TIMEIT Timing results for: SCAT >TIMEIT 0.006 = CPU time (sec) >DDSCAT return from DDSCAT to calling program ddscat main ckpt 1, NRFLD= 0 >DDSCAT normal termination, with no nearfield calculation >>> os.listdir('.') ['ddscat.par', 'mtable', 'output.log', 'qtable', 'qtable2', 'shape.dat', 'target.out', 'w000r000.avg', 'w001r000.avg', 'w002r000.avg', 'w003r000.avg', 'w004r000.avg']